diff -Nru libjna-java-4.2.2/AL2.0 libjna-java-4.4.0/AL2.0 --- libjna-java-4.2.2/AL2.0 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/AL2.0 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff -Nru libjna-java-4.2.2/ant-elfanalyser-src/com/sun/jna/BuildArmSoftFloatDetector.java libjna-java-4.4.0/ant-elfanalyser-src/com/sun/jna/BuildArmSoftFloatDetector.java --- libjna-java-4.2.2/ant-elfanalyser-src/com/sun/jna/BuildArmSoftFloatDetector.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/ant-elfanalyser-src/com/sun/jna/BuildArmSoftFloatDetector.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,53 @@ + +package com.sun.jna; + +import java.io.File; +import java.io.IOException; +import org.apache.tools.ant.Project; + +/** + * Ant task to expose the arm soft-/hardfloat detection routines of the JNA core + * for the build script. + * + *

The build script is expected to build a minimal set of classes that are + * required to execute this. At the time of writing these are:

+ * + * + */ +public class BuildArmSoftFloatDetector { + + private String targetProperty; + private Project project; + + public void setProject(Project proj) { + project = proj; + } + + /** + * targetProperty receives the name of the property, that should take the + * new property + * + * @param targetProperty + */ + public void setTargetProperty(String targetProperty) { + this.targetProperty = targetProperty; + } + + public void execute() throws IOException { + boolean result = false; + // On linux /proc/self/exe is a symblink to the currently executing + // binary (the JVM) + File self = new File("/proc/self/exe"); + try { + // The self.getCanonicalPath() resolves the symblink to the backing + // realfile and passes that to the detection routines + ELFAnalyser ahfd = ELFAnalyser.analyse(self.getCanonicalPath()); + result = ahfd.isArmSoftFloat(); + } catch (IOException ex) { + result = false; + } + project.setNewProperty(targetProperty, Boolean.toString(result)); + } +} diff -Nru libjna-java-4.2.2/ASL2.0 libjna-java-4.4.0/ASL2.0 --- libjna-java-4.2.2/ASL2.0 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/ASL2.0 1970-01-01 00:00:00.000000000 +0000 @@ -1,177 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS diff -Nru libjna-java-4.2.2/build.xml libjna-java-4.4.0/build.xml --- libjna-java-4.2.2/build.xml 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/build.xml 2017-03-14 19:31:03.000000000 +0000 @@ -31,6 +31,7 @@ + @@ -48,16 +49,16 @@ - - - + + + - - + + @@ -67,12 +68,12 @@ - - - + + + - + @@ -103,6 +104,7 @@ + @@ -120,10 +122,10 @@ - - - - + + + + @@ -206,6 +208,17 @@ + + + + + + + + + + + @@ -228,7 +241,15 @@ + + + + + + + + @@ -280,17 +301,19 @@ + - + + Java version ${java.version}, compatibility: ${compatibility}, ant: ${ant.java.version} - JNA version ${jna.version}, native ${jni.version} + JNA version ${jna.version}, native ${jni.version}, android ${android.versionCode} ${java.vm.name} (${java.vm.vendor}, ${java.vm.version}) java.home=${java.home} java.library.path=${java.library.path} @@ -299,6 +322,7 @@ os.arch=${os.arch} (${sun.cpu.endian}) build=${build} build.native=${build.native} + build.aar=${build.aar} @@ -307,6 +331,7 @@ + @@ -418,6 +443,8 @@ processor=x86-64;osname=linux, com/sun/jna/linux-arm/libjnidispatch.so; processor=arm;osname=linux, +com/sun/jna/linux-armel/libjnidispatch.so; +processor=armel;osname=linux, com/sun/jna/linux-aarch64/libjnidispatch.so; processor=aarch64;osname=linux, com/sun/jna/linux-ia64/libjnidispatch.so; @@ -462,6 +489,9 @@ + @@ -516,11 +546,59 @@ + + + + + + JNA bindings + + ]]> + int string jna_library_appname 0x7f050021 + + + + + ]]> + + + + + + + + + + + + + + + + - + @@ -543,11 +621,17 @@ - + + + + + + + @@ -606,6 +690,7 @@ + @@ -971,7 +1056,10 @@ - + + + + @@ -991,6 +1079,7 @@ + @@ -1025,7 +1114,7 @@ - + @@ -1073,6 +1162,7 @@ - - - + + @@ -1133,7 +1223,7 @@ - + @@ -1158,6 +1248,7 @@ + @@ -1166,6 +1257,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + @@ -1201,35 +1317,16 @@ - + - - - - - - - - - - - - - - - - - - - - - - + + + @@ -1240,32 +1337,10 @@ + + + - - - - - - - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff -Nru libjna-java-4.2.2/CHANGES.md libjna-java-4.4.0/CHANGES.md --- libjna-java-4.2.2/CHANGES.md 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/CHANGES.md 2017-03-14 19:31:03.000000000 +0000 @@ -1,24 +1,132 @@ -NOTE: as of JNA 4.0, JNA is now dual-licensed under LGPL and ASL (see LICENSE). +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 4.2.2 -============ +Release 4.4.0 +============================ + +Features +-------- +* [#757](https://github.com/java-native-access/jna/issues/757): Build android archive (AAR) - [@matthiasblaesing](https://github.com/matthiasblaesing). +* [#767](https://github.com/java-native-access/jna/pull/767): Add Win32 API mapping for Shlwapi PathIsUNC - [@ivanwick](https://github.com/ivanwick). +* [#753](https://github.com/java-native-access/jna/issues/753): Support arm hardfloat and softfloat by introducing armel as platform (ARM EABI Little-endian) - [@matthiasblaesing](https://github.com/matthiasblaesing). +* [#772](https://github.com/java-native-access/jna/pull/772): Improved speed of GDIUtil.getScreenshot() by ~30% - [@sommd](https://github.com/sommd). + +Bug Fixes +--------- +* [#754](https://github.com/java-native-access/jna/issues/754): Move MSVC build to standard stdbool.h and require Visual C++ 2015 (sizeof(bool) = 1 is now also true on MSVC build) - [@matthiasblaesing](https://github.com/matthiasblaesing). +* [#399](https://github.com/java-native-access/jna/issues/399): Check native version before attempting to call into native code - [@matthiasblaesing](https://github.com/matthiasblaesing). +* [#763](https://github.com/java-native-access/jna/issues/763): Fix vararg calls without fixed parts - [@matthiasblaesing](https://github.com/matthiasblaesing). +* [#770](https://github.com/java-native-access/jna/pull/770): Fix for free data handle in DdemlUtil. - [@stolarczykt](https://github.com/stolarczykt). + +Release 4.3.0 +============= + +Features +-------- +* [#526](https://github.com/java-native-access/jna/pull/526): Added initialization and conversion between Windows SYSTEMTIME and Java Calendar - [@lgoldstein](https://github.com/lgoldstein). +* [#532](https://github.com/java-native-access/jna/pull/529): Added `com.sun.jna.platform.win32.Mpr`, `com.sun.jna.platform.win32.LmShare`, and `com.sun.jna.platform.win32.Winnetwk` - [@amarcionek](https://github.com/amarcionek). +* [#532](https://github.com/java-native-access/jna/pull/529): Added `ACCESS_*` definitions to `com.sun.jna.platform.win32.LmAccess` - [@amarcionek](https://github.com/amarcionek). +* [#532](https://github.com/java-native-access/jna/pull/529): Added `NetShareAdd` and `NetShareDel` to `com.sun.jna.platform.win32.Netapi32` - [@amarcionek](https://github.com/amarcionek). +* [#535](https://github.com/java-native-access/jna/pull/535): Added `CreateProcessWithLogonW` to `com.sun.jna.platform.win32.Advapi32` - [@mlfreeman2](https://github.com/mlfreeman2). +* [#535](https://github.com/java-native-access/jna/pull/535): Added `CertAddEncodedCertificateToSystemStore` to `com.sun.jna.platform.win32.Crypt32` - [@mlfreeman2](https://github.com/mlfreeman2). +* [#535](https://github.com/java-native-access/jna/pull/535): Added `BitBlt` to `com.sun.jna.platform.win32.GDI32`, Added `com.sun.jna.platform.win32.GDI32Util` and added `getScreenshot()` to it - [@mlfreeman2](https://github.com/mlfreeman2). +* [#535](https://github.com/java-native-access/jna/pull/535): Added `SHEmptyRecycleBin`, `ShellExecuteEx` to `com.sun.jna.platform.win32.Shell32` - [@mlfreeman2](https://github.com/mlfreeman2). +* [#535](https://github.com/java-native-access/jna/pull/535): Added `GetDesktopWindow` to `com.sun.jna.platform.win32.User32` - [@mlfreeman2](https://github.com/mlfreeman2). +* [#540](https://github.com/java-native-access/jna/pull/539): Added Missing Windows kernel32 method: QueryFullProcessImageName - [@yossieilaty](https://github.com/yossieilaty). +* [#543](https://github.com/java-native-access/jna/pull/543): Added `ProcessIdToSessionId`, `LoadLibraryEx`, `FreeLibrary` and `Find/Load/Lock/SizeofResource` to `com.sun.jna.platform.win32.Kernel32` - [@mlfreeman2](https://github.com/mlfreeman2). +* [#545](https://github.com/java-native-access/jna/pull/545): Added `EnumResourceTypes` and `EnumResourceNames` to `com.sun.jna.platform.win32.Kernel32` - [@mlfreeman2](https://github.com/mlfreeman2). +* [#547](https://github.com/java-native-access/jna/pull/547): Added `GetSystemTimes` to `com.sun.jna.platform.win32.Kernel32` - [@dbwiddis](https://github.com/dbwiddis). +* [#548](https://github.com/java-native-access/jna/pull/548): Return 64-bit unsigned integer from `com.sun.jna.platform.win32.WinBase.FILETIME` - [@dbwiddis](https://github.com/dbwiddis). +* [#524](https://github.com/java-native-access/jna/pull/524): Added IShellFolder interface plus necessary utility functions to Windows platform, and a sample for enumerating objects in My Computer - [@lwahonen](https://github.com/lwahonen). +* [#471](https://github.com/java-native-access/jna/issues/471): Determine size of native `bool` - [@twall](https://github.com/twall). +* [#484](https://github.com/java-native-access/jna/pull/484): Added `XFetchName` to `X11` interface - [@pinaf](https://github.com/pinaf). +* [#554](https://github.com/java-native-access/jna/pull/554): Initial code for a few Unix 'libc' API(s) [@lgoldstein](https://github.com/lgoldstein) +* [#552](https://github.com/java-native-access/jna/pull/552): Added `Module32FirstW` and `Module32NextW` to `com.sun.jna.platform.win32.Kernel32` (and helper to `com.sun.jna.platform.win32.Kernel32Util`) and `MODULEENTRY32W` structure to `com.sun.jna.platform.win32.Tlhelp32` - [@mlfreeman2](https://github.com/mlfreeman2). +* [#564](https://github.com/java-native-access/jna/pull/564): Use generic definition of Native#loadLibrary [@lgoldstein](https://github.com/lgoldstein) +* [#562](https://github.com/java-native-access/jna/pull/562): Added `com.sun.jna.platform.win32.VersionUtil` with `getFileVersionInfo` utility method to get file major, minor, revision, and build version parts - [@mlfreeman2](https://github.com/mlfreeman2). +* [#563](https://github.com/java-native-access/jna/pull/563): Added `com.sun.jna.platform.win32.Wininet` with the following 4 methods: `FindFirstUrlCacheEntry`, `DeleteUrlCacheEntry`, `FindCloseUrlCache`, `FindNextUrlCacheEntry`, and the `INTERNET_CACHE_ENTRY_INFO` structure, and a helper in `com.sun.jna.platform.win32.WininetUtil` for parsing WinInet's cache - [@mlfreeman2](https://github.com/mlfreeman2). +* [#567](https://github.com/java-native-access/jna/pull/567): Added `PrintWindow`, `IsWindowEnabled`, `IsWindow`, `FindWindowEx`, `GetAncestor`, `GetCursorPos`, `SetCursorPos`, `SetWinEventHook`, `UnhookWinEvent`, `CopyIcon`, and `GetClassLong` to `com.sun.jna.platform.win32.User32` and supporting constants to `com.sun.jna.platform.win32.WinUser` - [@mlfreeman2](https://github.com/mlfreeman2). +* [#573](https://github.com/java-native-access/jna/pull/573): Added `EnumProcessModules`, `GetModuleInformation`, and `GetProcessImageFileName` to `com.sun.jna.platform.win32.Psapi` and added `ExtractIconEx` to `com.sun.jna.platform.win32.Shell32` - [@mlfreeman2](https://github.com/mlfreeman2). +* [#574](https://github.com/java-native-access/jna/pull/574): Using static final un-modifiable List of field names for structure(s) - [@lgoldstein](https://github.com/lgoldstein). +* [#577](https://github.com/java-native-access/jna/pull/577): Apply generic definitions wherever applicable - [@lgoldstein](https://github.com/lgoldstein). +* [#569](https://github.com/java-native-access/jna/pull/569): Added `com.sun.jna.platform.win32.Winspool.PRINTER_INFO_2` support. Added GetPrinter and ClosePrinter functions in `com.sun.jna.platform.win32.Winspool` - [@IvanRF](https://github.com/IvanRF). +* [#583](https://github.com/java-native-access/jna/pull/583): Added printer attributes and status - [@IvanRF](https://github.com/IvanRF). +* [#589](https://github.com/java-native-access/jna/pull/589): Use `com.sun.jna.MethodResultContext` in direct mapping (as done in interface mapping) - [@marco2357](https://github.com/marco2357). +* [#595](https://github.com/java-native-access/jna/pull/595): Allow calling COM methods/getters requiring hybrid calling (METHOD+PROPERTYGET) - [@matthiasblaesing](https://github.com/matthiasblaesing). +* [#582](https://github.com/java-native-access/jna/pull/582): Mavenize the build process - Phase 1: building the native code via Maven - [@lgoldstein](https://github.com/lgoldstein). +* [#606](https://github.com/java-native-access/jna/pull/606): Added Kernel32Util method to facilitate checking that calls to LocalFree/GlobalFree are successful - [@lgoldstein](https://github.com/lgoldstein). +* [#612](https://github.com/java-native-access/jna/pull/612): `Kernel32Util.freeLocalMemory()`/`Kernel32Util.freeGlobalMemory()` always throw `com.sun.jna.platform.win32.Win32Exception` if failed - [@lgoldstein](https://github.com/lgoldstein). +* [#608](https://github.com/java-native-access/jna/pull/608): Mavenize the build process - change parent and native pom artifactId/name to differentiate in IDE and build tools. - [@bhamail](https://github.com/bhamail) +* [#613](https://github.com/java-native-access/jna/pull/613): Make `com.sun.jna.platform.win32.Win32Exception` extend `com.sun.jna.LastErrorException` - [@lgoldstein](https://github.com/lgoldstein). +* [#614](https://github.com/java-native-access/jna/pull/614): Added standard `com.sun.jna.platform.win32.Kernel32Util.closeHandle()` method that throws a `com.sun.jna.platform.win32.Win32Exception` if failed to close the handle - [@lgoldstein](https://github.com/lgoldstein). +* [#618](https://github.com/java-native-access/jna/pull/618): Implement SAFEARRAY access and bugfix VARIANT - [@matthiasblaesing](https://github.com/matthiasblaesing). +* [#616](https://github.com/java-native-access/jna/pull/616): Allow access to base interfaces (most important IDispatch) via ProxyObject and improve binding by allowing to use dispId for the call - [@matthiasblaesing](https://github.com/matthiasblaesing). +* [#621](https://github.com/java-native-access/jna/pull/621): Added TYPEFLAGS-constants for `wTypeFlags` in `com.sun.jna.platform.win32.OaIdl.TYPEATTR` - [@SevenOf9Sleeper](https://github.com/SevenOf9Sleeper). +* [#625](https://github.com/java-native-access/jna/pull/625): Make conversion to/from java to/from VARIANT in `com.sun.jna.platform.win32.COM.util.Convert` more flexible and dependable - [@matthiasblaesing](https://github.com/matthiasblaesing). +* [#639](https://github.com/java-native-access/jna/pull/639): Add getloadavg() to OS X and Unix - [@dbwiddis](https://github.com/dbwiddis). +* [#640](https://github.com/java-native-access/jna/pull/640): Add `com.sun.jna.platform.win32.Psapi.GetPerformanceInfo()`, `com.sun.jna.platform.win32.Kernel32.GetTickCount64()`, and `com.sun.jna.platform.win32.Kernel32.SetErrorMode()` - [@dbwiddis](https://github.com/dbwiddis). +* [#642](https://github.com/java-native-access/jna/pull/642): COM calls with variable number of arguments (varargs) are now supported - [@SevenOf9Sleeper](https://github.com/SevenOf9Sleeper). +* [#644](https://github.com/java-native-access/jna/pull/644): New ant target 'install' for installing JNA artifacts in local m2-repository - [@SevenOf9Sleeper](https://github.com/SevenOf9Sleeper). +* [#649](https://github.com/java-native-access/jna/pull/649): Bugfix msoffice sample and add two samples taken from MSDN and translated from VisualBasic to Java - [@matthiasblaesing](https://github.com/matthiasblaesing). +* [#654](https://github.com/java-native-access/jna/pull/654): Support named arguments for `com.sun.jna.platform.win32.COM.util.CallbackProxy` based callbacks - [@matthiasblaesing](https://github.com/matthiasblaesing). +* [#659](https://github.com/java-native-access/jna/issues/659): Enable LCID (locale) override for `com.sun.jna.platform.win32.COM.util.ProxyObject`-based COM calls - [@matthiasblaesing](https://github.com/matthiasblaesing). +* [#665](https://github.com/java-native-access/jna/pull/665): Added `XSetWMProtocols` and `XGetWMProtocols` to `com.sun.jna.platform.unix.X11` - [@zainab-ali](https://github.com/zainab-ali). +* [#667](https://github.com/java-native-access/jna/pull/667): Added SetFileSecurity, GetSecurityInfo and SetSecurityInfo to `com.sun.jna.platform.win32.Advapi32` - [@amarcionek](https://github.com/amarcionek). +* [#667](https://github.com/java-native-access/jna/pull/667): Added NtSetSecurityObject and NtQuerySecurityObject to `com.sun.jna.platform.win32.NtDll` - [@amarcionek](https://github.com/amarcionek). +* [#680](https://github.com/java-native-access/jna/pull/680): Added `SetCurrentProcessExplicitAppUserModelID` and `GetCurrentProcessExplicitAppUserModelID` to `com.sun.jna.platform.win32.Shell32` for setting the [System.AppUserModel.ID](https://msdn.microsoft.com/en-us/library/windows/desktop/dd391569.aspx) of the host process - [@rednoah](https://github.com/rednoah). +* [#693](https://github.com/java-native-access/jna/pull/693): Bind DDEML (Dynamic Data Exchange Management Library), add a thread implementation that runs a windows message loop - [@matthiasblaesing](https://github.com/matthiasblaesing). +* [#702](https://github.com/java-native-access/jna/pull/702): Added `GetClientRect` to `com/sun/jna/platform/win32/User32` - [@Jonatino](https://github.com/Jonatino). +* [#689](https://github.com/java-native-access/jna/pull/689): Add `GetProcAddress(HMODULE, int)` to `com.sun.jna.platform.win32.Kernel32` - [@matthiasblaesing](https://github.com/matthiasblaesing). +* [#723](https://github.com/java-native-access/jna/pull/723): Added `com.sun.jna.platform.win32.Wevtapi` and `com.sun.jna.platform.win32.Winevt` - [@sakamotodesu](https://github.com/sakamotodesu). +* [#720](https://github.com/java-native-access/jna/issues/720): Added `SetThreadExecutionState` to `com.sun.jna.platform.win32.Kernel32` - [@matthiasblaesing](https://github.com/matthiasblaesing). +* [#738](https://github.com/java-native-access/jna/pull/738): Added `GetSecurityDescriptorOwner`, `SetSecurityDescriptorOwner`, `GetSecurityDescriptorGroup`, `SetSecurityDescriptorGroup`, `GetSecurityDescriptorControl`, `SetSecurityDescriptorControl`, `GetSecurityDescriptorDacl`, `SetSecurityDescriptorDacl`, `MakeSelfRelativeSD`, `MakeAbsoluteSD`, `EqualSid`, `InitializeSecurityDescriptor`, `InitializeAcl`, `AddAce`, `AddAccessAllowedAce`, `AddAccessAllowedAceEx`, and `GetAce` to `com.sun.jna.platform.win32.Advapi32 - [@amarcionek](https://github.com/amarcionek). +* [#738](https://github.com/java-native-access/jna/pull/738): Added `RtlNtStatusToDosError` to `com.sun.jna.platform.win32.NtDll - [@amarcionek](https://github.com/amarcionek). +* [#732](https://github.com/java-native-access/jna/pull/732): Added `com.sun.jna.platform.win32.WinioctlUtil` for help in determining FSCTL_* codes - [@amarcionek](https://github.com/amarcionek). +* [#732](https://github.com/java-native-access/jna/pull/732): Added `com.sun.jna.platform.win32.Ntifs` with Reparse Point structures and defines - [@amarcionek](https://github.com/amarcionek). +* [#732](https://github.com/java-native-access/jna/pull/732): Added initialization of FILETIME from LARGE_INTEGER - [@amarcionek](https://github.com/amarcionek). +* [#732](https://github.com/java-native-access/jna/pull/732): Added `GetFileInformationByHandleEx` and `SetFileInformationByHandle` to `com.sun.jna.platform.win32.Kernel32` - [@amarcionek](https://github.com/amarcionek). +* [#740](https://github.com/java-native-access/jna/pull/740): Modified `com.sun.jna.platform.win32.WinioctlUtil` for simplicity dealing with FSCTL_* codes - [@amarcionek](https://github.com/amarcionek). +* [#745](https://github.com/java-native-access/jna/pull/745): Added Secur32#QueryContextAttributes - [@barney2k7](https://github.com/barney2k7). Bug Fixes --------- * [#549](https://github.com/java-native-access/jna/pull/549): Fixed bug in types derived from XID - [@twall](https://github.com/twall). +* [#536](https://github.com/java-native-access/jna/pull/536): Fixed bug in determining the Library and options associated with types defined outside of a Library - [@twall](https://github.com/twall). +* [#531](https://github.com/java-native-access/jna/pull/531): Ensure direct-mapped callbacks use the right calling convention - [@twall](https://github.com/twall). +* [#566](https://github.com/java-native-access/jna/pull/566): Fix return type of Native#loadLibrary to match unconstrained generic [@lgoldstein](https://github.com/lgoldstein). +* [#584](https://github.com/java-native-access/jna/pull/584): Promote float varargs to double - [@marco2357](https://github.com/marco2357). +* [#588](https://github.com/java-native-access/jna/pull/588): Fix varargs calls on arm - [@twall](https://github.com/twall). +* [#593](https://github.com/java-native-access/jna/pull/593): Improve binding of TypeLib bindings - [@matthiasblaesing](https://github.com/matthiasblaesing). +* [#578](https://github.com/java-native-access/jna/pull/578): Fix COM CallbackHandlers, allow usage of VARIANTs directly in c.s.j.p.w.COM.util.ProxyObject and fix native memory leak in c.s.j.p.w.COM.util.ProxyObject - [@matthiasblaesing](https://github.com/matthiasblaesing) +* [#601](https://github.com/java-native-access/jna/pull/601): Remove COMThread and COM initialization from objects and require callers to initialize COM themselves. Asserts are added to guard correct usage. - [@matthiasblaesing](https://github.com/matthiasblaesing). +* [#602](https://github.com/java-native-access/jna/pull/602): Make sure SID related memory is properly released once no longer required [@lgoldstein](https://github.com/lgoldstein). +* [#610](https://github.com/java-native-access/jna/pull/610): Fixed issue #604: Kernel32#GetLastError() always returns ERROR_SUCCESS [@lgoldstein](https://github.com/lgoldstein). +* [#633](https://github.com/java-native-access/jna/pull/633): Restore default usage of platform native encoding for Java strings passed to native functions (was hard-coded to UTF-8 in 4.0 and later) [@amake](https://github.com/amake) +* [#634](https://github.com/java-native-access/jna/pull/634): Improve BSTR handling and add `SysStringByteLen` and `SysStringLen` to `com.sun.jna.platform.win32.OleAuto` - [@matthiasblaesing](https://github.com/matthiasblaesing). +* [#646](https://github.com/java-native-access/jna/issues/646): `platform.win32.COM.COMBindingBaseObject` swallows reason if instantiation fails - [@matthiasblaesing](https://github.com/matthiasblaesing). +* [#674](https://github.com/java-native-access/jna/pull/674): Update references to Apache License as requested by issue #673 [@bhamail](https://github.com/bhamail) +* [#636](https://github.com/java-native-access/jna/issues/636): Staticly link visual c++ runtime when building with MSVC - [@matthiasblaesing](https://github.com/matthiasblaesing). +* [#624](https://github.com/java-native-access/jna/issues/624): WinDef.DWORD getLow() & getHigh() using incorrect bit mask - [@matthiasblaesing](https://github.com/matthiasblaesing). +* [#668](https://github.com/java-native-access/jna/issues/668): Correct typemapper used for structures defined in `com.sun.jna.platform.win32.DsGetDC`, `com.sun.jna.platform.win32.LMAccess`, `com.sun.jna.platform.win32.LMShare`, `com.sun.jna.platform.win32.Sspi`, `com.sun.jna.platform.win32.WinBase`, `com.sun.jna.platform.win32.WinCrypt`, `com.sun.jna.platform.win32.WinUser` and `com.sun.jna.platform.win32.Winnetwk` - [@matthiasblaesing](https://github.com/matthiasblaesing). +* [#696](https://github.com/java-native-access/jna/issues/696): COMLateBindingObject.getAutomationProperty method that takes iDispatch parameter doesn't use it - [@matthiasblaesing](https://github.com/matthiasblaesing). +* [#664](https://github.com/java-native-access/jna/issues/664): Prevent premature GC of Pointer and Function objects by passing whole object into JNI call in addition to the raw pointer value - [@matthiasblaesing](https://github.com/matthiasblaesing). +* [#669](https://github.com/java-native-access/jna/pull/669): Ensure XSI-compliant strerror_r is used, to prevent corrupted error messages on linux - [@DavidKeller](https://github.com/DavidKeller). +* [#697](https://github.com/java-native-access/jna/issues/697): Ensure disposed memory is removed from Memory#allocatedMemory map - [@matthiasblaesing](https://github.com/matthiasblaesing). +* [#731](https://github.com/java-native-access/jna/issues/731): Require mingw-w64 instead of mingw as the alternative to the MSVC build - [@matthiasblaesing](https://github.com/matthiasblaesing). +* [#747](https://github.com/java-native-access/jna/issues/747): - Call `Native.toString()` in `#getFileName()` and `#getAlternateFileName()` in `c.s.j.p.win32.WinBase` instead of custom NUL terminator logic - [@jhult](https://github.com/jhult). Release 4.2.1 ============= Features -------- -* [#504](https://github.com/java-native-access/jna/pull/504): Add support for linux-sparcv9 [@alexvsimon](https://github.com/alexvsimon). +* [#504](https://github.com/java-native-access/jna/pull/504): Add support for linux-sparcv9 - [@alexvsimon](https://github.com/alexvsimon). * [#510](https://github.com/java-native-access/jna/pull/510): Added `GetCommState`, `GetCommTimeouts` `SetCommState` and `SetCommTimeouts` to `com.sun.jna.platform.win32.Kernel32`. Added `DCB` structure to `com.sun.jna.platform.win32.WinBase` - [@MBollig](https://github.com/MBollig). * [#512](https://github.com/java-native-access/jna/pull/512): Make loading debug flags mutable [@lwahonen](https://github.com/lwahonen). * [#514](https://github.com/java-native-access/jna/pull/514): Added `host_processor_info` to `com.sun.jna.platform.mac.SystemB` - [@dbwiddis](https://github.com/dbwiddis). * [#519](https://github.com/java-native-access/jna/pull/519): Added JNA functional overview - [@twall](https://github.com/twall). +* [#528](https://github.com/java-native-access/jna/pull/528): Added idea-jar ant task that creates a convenience jar that contains all native dispatch libraries - [@lwahonen](https://github.com/lwahonen). Bug Fixes --------- @@ -93,10 +201,10 @@ * Remove unsupported JAWT from OSX build - [@twall](https://github.com/twall). * Disable WebStart tests - [@twall](https://github.com/twall). * Dispose all native resources when JNA's native library is unloaded - Paul Grütter, [@twall](https://github.com/twall). -* Weakly hold registered direct-mapped classes - [@twall](https://github.com/twall). +* Weakly hold registered direct-mapped classes - [@twall](https://github.com/twall). * [#382](https://github.com/java-native-access/jna/pull/382): Fixed memory allocation in `com.sun.jna.platform.win32.WTypes.LPWSTR` and `LPSTR` constructors - [@junak-michal](https://github.com/junak-michal). * Fix publish doc links - [@bhamail](https://github.com/bhamail). -* [#388](https://github.com/java-native-access/jna/issues/388): Ensure native library always opened with provided flags - [@zolyfarkas](https://github.com/zolyfarkas). +* [#388](https://github.com/java-native-access/jna/issues/388): Ensure native library always opened with provided flags - [@zolyfarkas](https://github.com/zolyfarkas). * [#403](https://github.com/java-native-access/jna/pull/403): Fix `com.sun.jna.platform.win32.COM.COMUtils.SUCCEEDED` and `FAILED` - [@lwahonen](https://github.com/lwahonen). * [#404](https://github.com/java-native-access/jna/pull/404): Fix `VARIANT` constructors for `int`, `short`, and `long` - [@lwahonen](https://github.com/lwahonen). * [#420](https://github.com/java-native-access/jna/pull/420): Fix structure leaving always one element in ThreadLocal set - [@sjappig](https://github.com/sjappig). diff -Nru libjna-java-4.2.2/contrib/alphamaskdemo/com/sun/jna/contrib/demo/AlphaMaskDemo2.java libjna-java-4.4.0/contrib/alphamaskdemo/com/sun/jna/contrib/demo/AlphaMaskDemo2.java --- libjna-java-4.2.2/contrib/alphamaskdemo/com/sun/jna/contrib/demo/AlphaMaskDemo2.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/alphamaskdemo/com/sun/jna/contrib/demo/AlphaMaskDemo2.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,12 +1,26 @@ /* - * Copyright (c) 2007-2008 Timothy Wall, All Rights Reserved This library is - * free software; you can redistribute it and/or modify it under the - * terms of the GNU Lesser General Public License as published by the - * Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. This library is distributed in the - * hope that it will be useful, but WITHOUT ANY WARRANTY; without even - * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU Lesser General Public License for more details. + * Copyright (c) 2007-2008 Timothy Wall, 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.contrib.demo; diff -Nru libjna-java-4.2.2/contrib/alphamaskdemo/com/sun/jna/contrib/demo/AlphaMaskDemo.java libjna-java-4.4.0/contrib/alphamaskdemo/com/sun/jna/contrib/demo/AlphaMaskDemo.java --- libjna-java-4.2.2/contrib/alphamaskdemo/com/sun/jna/contrib/demo/AlphaMaskDemo.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/alphamaskdemo/com/sun/jna/contrib/demo/AlphaMaskDemo.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007-2008 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.contrib.demo; diff -Nru libjna-java-4.2.2/contrib/balloonmanagerdemo/com/sun/jna/contrib/demo/BalloonManagerDemo.java libjna-java-4.4.0/contrib/balloonmanagerdemo/com/sun/jna/contrib/demo/BalloonManagerDemo.java --- libjna-java-4.2.2/contrib/balloonmanagerdemo/com/sun/jna/contrib/demo/BalloonManagerDemo.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/balloonmanagerdemo/com/sun/jna/contrib/demo/BalloonManagerDemo.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.contrib.demo; diff -Nru libjna-java-4.2.2/contrib/balloonmanagerdemo/com/sun/jna/contrib/demo/BalloonManager.java libjna-java-4.4.0/contrib/balloonmanagerdemo/com/sun/jna/contrib/demo/BalloonManager.java --- libjna-java-4.2.2/contrib/balloonmanagerdemo/com/sun/jna/contrib/demo/BalloonManager.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/balloonmanagerdemo/com/sun/jna/contrib/demo/BalloonManager.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,26 @@ /* * Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version.

This library is distributed in - * the hope that it will be useful, but WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR A - * PARTICULAR PURPOSE. See the GNU Lesser General Public License for - * more details. + * 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.contrib.demo; diff -Nru libjna-java-4.2.2/contrib/balloontips/com/sun/jna/contrib/demo/BalloonTipManager.java libjna-java-4.4.0/contrib/balloontips/com/sun/jna/contrib/demo/BalloonTipManager.java --- libjna-java-4.2.2/contrib/balloontips/com/sun/jna/contrib/demo/BalloonTipManager.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/balloontips/com/sun/jna/contrib/demo/BalloonTipManager.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,3 +1,25 @@ +/* + * 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.contrib.demo; import java.awt.Color; diff -Nru libjna-java-4.2.2/contrib/balloontips/com/sun/jna/contrib/demo/FilteredTextField.java libjna-java-4.4.0/contrib/balloontips/com/sun/jna/contrib/demo/FilteredTextField.java --- libjna-java-4.2.2/contrib/balloontips/com/sun/jna/contrib/demo/FilteredTextField.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/balloontips/com/sun/jna/contrib/demo/FilteredTextField.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,3 +1,25 @@ +/* + * 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.contrib.demo; import java.awt.BorderLayout; diff -Nru libjna-java-4.2.2/contrib/dnddemo/com/sun/jna/contrib/demo/GhostedDragImageDemo.java libjna-java-4.4.0/contrib/dnddemo/com/sun/jna/contrib/demo/GhostedDragImageDemo.java --- libjna-java-4.2.2/contrib/dnddemo/com/sun/jna/contrib/demo/GhostedDragImageDemo.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/dnddemo/com/sun/jna/contrib/demo/GhostedDragImageDemo.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.contrib.demo; diff -Nru libjna-java-4.2.2/contrib/monitordemo/build.xml libjna-java-4.4.0/contrib/monitordemo/build.xml --- libjna-java-4.2.2/contrib/monitordemo/build.xml 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/monitordemo/build.xml 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,68 @@ + + + Builds, tests, and runs the project jnacontrib.monitordemo. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru libjna-java-4.2.2/contrib/monitordemo/src/com/sun/jna/contrib/demo/MonitorInfoDemo.java libjna-java-4.4.0/contrib/monitordemo/src/com/sun/jna/contrib/demo/MonitorInfoDemo.java --- libjna-java-4.2.2/contrib/monitordemo/src/com/sun/jna/contrib/demo/MonitorInfoDemo.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/monitordemo/src/com/sun/jna/contrib/demo/MonitorInfoDemo.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,17 +1,26 @@ /* * Copyright 2014 Martin Steiger * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * 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.contrib.demo; diff -Nru libjna-java-4.2.2/contrib/msoffice/build.xml libjna-java-4.4.0/contrib/msoffice/build.xml --- libjna-java-4.2.2/contrib/msoffice/build.xml 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/build.xml 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,68 @@ + + + Builds, tests, and runs the project jnacontrib.msoffice. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Binary files /tmp/tmptdXlQx/zXsTgf0UHo/libjna-java-4.2.2/contrib/msoffice/jnatest.doc and /tmp/tmptdXlQx/nhswvPAIcW/libjna-java-4.4.0/contrib/msoffice/jnatest.doc differ Binary files /tmp/tmptdXlQx/zXsTgf0UHo/libjna-java-4.2.2/contrib/msoffice/jnatest.xls and /tmp/tmptdXlQx/nhswvPAIcW/libjna-java-4.4.0/contrib/msoffice/jnatest.xls differ diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/COMInfoUtil.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/COMInfoUtil.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/COMInfoUtil.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/COMInfoUtil.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,18 +1,41 @@ +/* + * 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.COM; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; -import com.sun.jna.platform.win32.COM.COMUtils; import com.sun.jna.platform.win32.COM.COMUtils.COMInfo; +import java.io.File; public class COMInfoUtil { public static void main(String[] args) { FileWriter writer = null; try { - String filename = "C:\\TEMP\\CLSIDs.txt"; + String filename = new File(Helper.tempDir, "CLSIDs.txt").getAbsolutePath(); ArrayList comInfos = COMUtils.getAllCOMInfoOnSystem(); writer = new FileWriter(filename); diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/Helper.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/Helper.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/Helper.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/Helper.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,97 @@ +/* + * 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.COM; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; + +public class Helper { + public static final File tempDir = new File(System.getProperty("java.io.tmpdir")); + + /** + * Sleep for specified seconds. + * + * @param seconds + */ + public static void sleep(int seconds) { + try { + Thread.sleep(seconds * 1000L); + } catch (InterruptedException ex) { + // Ignore + } + } + + /** + * Extract data contained in classpath into a system accessible target file. + * + * @param localPath + * @param target + * @throws IOException + */ + public static void extractClasspathFileToReal(String localPath, File target) throws IOException { + InputStream is = null; + OutputStream os = null; + try { + is = Helper.class.getResourceAsStream(localPath); + os = new FileOutputStream(target); + + int read; + byte[] buffer = new byte[20480]; + + while((read = is.read(buffer)) > 0) { + os.write(buffer, 0, read); + } + + } finally { + if(is != null) { + try { + is.close(); + } catch(Exception ex) {} + } + if(os != null) { + try { + os.close(); + } catch(Exception ex) {} + } + } + } + + /** + * Create a temporary file, that does not exist. + * + * @param prefix + * @param suffix + * @return + * @throws IOException + */ + public static File createNotExistingFile(String prefix, String suffix) throws IOException { + File tempFile = Files.createTempFile(prefix, suffix).toFile(); + tempFile.delete(); + return tempFile; + } +} diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/office/MSExcel.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/office/MSExcel.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/office/MSExcel.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/office/MSExcel.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,3 +1,26 @@ +/* + * 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.COM.office; import com.sun.jna.platform.win32.Variant.VARIANT; @@ -28,9 +51,7 @@ this.invokeNoReply("Add", getWorkbooks()); } - public void openExcelBook(String filename, boolean bVisible) - throws COMException { - // OpenDocument + public void openExcelBook(String filename) throws COMException { this.invokeNoReply("Open", getWorkbooks(), new VARIANT(filename)); } diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/office/MSOfficeDemo.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/office/MSOfficeDemo.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/office/MSOfficeDemo.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/office/MSOfficeDemo.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,28 +1,51 @@ +/* + * 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.COM.office; -import java.io.File; +import com.sun.jna.Pointer; import com.sun.jna.platform.win32.COM.COMException; +import com.sun.jna.platform.win32.COM.Helper; +import com.sun.jna.platform.win32.Ole32; import com.sun.jna.platform.win32.WinDef.LONG; +import java.io.File; +import java.io.IOException; public class MSOfficeDemo { - - /** - * @param args - */ - public static void main(String[] args) { - new MSOfficeDemo(); - } - - private String currentWorkingDir = new File("").getAbsolutePath() - + File.separator; - - public MSOfficeDemo() { - //this.testMSWord(); - this.testMSExcel(); + public static void main(String[] args) throws IOException { + Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED); + try { + MSOfficeDemo demo = new MSOfficeDemo(); + demo.testMSExcel(); + demo.testMSWord(); + } finally { + Ole32.INSTANCE.CoUninitialize(); + } } - public void testMSWord() { + public void testMSWord() throws IOException { + File demoDocument = null; MSWord msWord = null; // http://msdn.microsoft.com/en-us/library/office/ff839952(v=office.15).aspx @@ -42,82 +65,92 @@ System.out.println("MSWord version: " + msWord.getVersion()); msWord.setVisible(true); - // msWord.newDocument(); - msWord.openDocument(currentWorkingDir + "jnatest.doc", true); + + Helper.sleep(5); + + demoDocument = Helper.createNotExistingFile("jnatest", ".doc"); + Helper.extractClasspathFileToReal("/com/sun/jna/platform/win32/COM/util/office/resources/jnatest.doc", demoDocument); + + msWord.openDocument(demoDocument.getAbsolutePath()); msWord.insertText("Hello from JNA! \n\n"); // wait 10sec. before closing - Thread.currentThread().sleep(1000); + Helper.sleep(10); // save in different formats // pdf format is only supported in MSWord 2007 and above - msWord.SaveAs("C:\\TEMP\\jnatestSaveAs.doc", wdFormatDocument); - msWord.SaveAs("C:\\TEMP\\jnatestSaveAs.pdf", wdFormatPDF); - msWord.SaveAs("C:\\TEMP\\jnatestSaveAs.rtf", wdFormatRTF); - msWord.SaveAs("C:\\TEMP\\jnatestSaveAs.html", wdFormatHTML); + System.out.println("Wrinting files to: " + Helper.tempDir); + msWord.SaveAs(new File(Helper.tempDir, "jnatestSaveAs.doc").getAbsolutePath(), wdFormatDocument); + msWord.SaveAs(new File(Helper.tempDir, "jnatestSaveAs.pdf").getAbsolutePath(), wdFormatPDF); + msWord.SaveAs(new File(Helper.tempDir, "jnatestSaveAs.rtf").getAbsolutePath(), wdFormatRTF); + msWord.SaveAs(new File(Helper.tempDir, "jnatestSaveAs.html").getAbsolutePath(), wdFormatHTML); // close and save the document msWord.closeActiveDocument(false); msWord.newDocument(); // msWord.openDocument(currentWorkingDir + "jnatest.doc", true); msWord.insertText("Hello from JNA! \n Please notice that JNA can control MS Word via the new COM interface! \nHere we are creating a new word document and we save it to the 'TEMP' directory!"); // save with no user prompt - msWord.SaveAs("C:\\TEMP\\jnatestNewDoc1.docx", wdFormatDocumentDefault); - msWord.SaveAs("C:\\TEMP\\jnatestNewDoc2.docx", wdFormatDocumentDefault); - msWord.SaveAs("C:\\TEMP\\jnatestNewDoc3.docx", wdFormatDocumentDefault); + msWord.SaveAs(new File(Helper.tempDir, "jnatestNewDoc1.docx").getAbsolutePath(), wdFormatDocumentDefault); + msWord.SaveAs(new File(Helper.tempDir, "jnatestNewDoc2.docx").getAbsolutePath(), wdFormatDocumentDefault); + msWord.SaveAs(new File(Helper.tempDir, "jnatestNewDoc3.docx").getAbsolutePath(), wdFormatDocumentDefault); // close and save the document msWord.closeActiveDocument(false); // open 3 documents - msWord.openDocument("C:\\TEMP\\jnatestNewDoc1.docx", true); + msWord.openDocument(new File(Helper.tempDir, "jnatestNewDoc1.docx").getAbsolutePath()); msWord.insertText("Hello some changes from JNA!\n"); - msWord.openDocument("C:\\TEMP\\jnatestNewDoc2.docx", true); + msWord.openDocument(new File(Helper.tempDir, "jnatestNewDoc2.docx").getAbsolutePath()); msWord.insertText("Hello some changes from JNA!\n"); - msWord.openDocument("C:\\TEMP\\jnatestNewDoc3.docx", true); + msWord.openDocument(new File(Helper.tempDir, "jnatestNewDoc3.docx").getAbsolutePath()); msWord.insertText("Hello some changes from JNA!\n"); // save the document and prompt the user msWord.Save(false, wdPromptUser); - // wait then close word - msWord.quit(); - } catch(InterruptedException ie) { - ie.printStackTrace(); } catch (COMException e) { if (e.getExcepInfo() != null) { - System.out - .println("bstrSource: " + e.getExcepInfo().bstrSource); - System.out.println("bstrDescription: " - + e.getExcepInfo().bstrDescription); + System.out.println("bstrSource: " + e.getExcepInfo().bstrSource); + System.out.println("bstrDescription: " + e.getExcepInfo().bstrDescription); } - - // print stack trace - e.printStackTrace(); - - if (msWord != null) + } finally { + if (msWord != null) { msWord.quit(); + } + + if(demoDocument != null && demoDocument.exists()) { + demoDocument.delete(); + } } } - public void testMSExcel() { + public void testMSExcel() throws IOException { + File demoDocument = null; MSExcel msExcel = null; try { msExcel = new MSExcel(); System.out.println("MSExcel version: " + msExcel.getVersion()); msExcel.setVisible(true); - // msExcel.newExcelBook(); - msExcel.openExcelBook(currentWorkingDir + "jnatest.xls", true); + + Helper.sleep(5); + + demoDocument = Helper.createNotExistingFile("jnatest", ".xls"); + Helper.extractClasspathFileToReal("/com/sun/jna/platform/win32/COM/util/office/resources/jnatest.xls", demoDocument); + + msExcel.openExcelBook(demoDocument.getAbsolutePath()); msExcel.insertValue("A1", "Hello from JNA!"); // wait 10sec. before closing - Thread.currentThread().sleep(10000); + Helper.sleep(10); // close and save the active sheet msExcel.closeActiveWorkbook(true); - msExcel.setVisible(true); - // msExcel.newExcelBook(); - msExcel.openExcelBook(currentWorkingDir + "jnatest.xls", true); + + msExcel.newExcelBook(); msExcel.insertValue("A1", "Hello from JNA!"); // close and save the active sheet msExcel.closeActiveWorkbook(true); - } catch (Exception e) { - e.printStackTrace(); - - if (msExcel != null) + } finally { + if (msExcel != null) { msExcel.quit(); + } + + if (demoDocument != null && demoDocument.exists()) { + demoDocument.delete(); + } } } } diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/office/MSWord.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/office/MSWord.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/office/MSWord.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/office/MSWord.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,3 +1,26 @@ +/* + * 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.COM.office; import com.sun.jna.platform.win32.Variant.VARIANT; @@ -29,9 +52,7 @@ this.invokeNoReply("Add", getDocuments()); } - public void openDocument(String filename, boolean bVisible) - throws COMException { - // OpenDocument + public void openDocument(String filename) throws COMException { this.invokeNoReply("Open", getDocuments(), new VARIANT(filename)); } @@ -70,7 +91,6 @@ } public Documents getDocuments() { - // GetDocuments Documents pDocuments = new Documents(this.getAutomationProperty( "Documents", this.getApplication().getIDispatch())); diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/Borders.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/Borders.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/Borders.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/Borders.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,42 @@ +/* + * 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.COM.util.office.excel; + +import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; +import com.sun.jna.platform.win32.COM.util.annotation.ComProperty; + +@ComInterface +public interface Borders { + @ComProperty + XlBorderWeight getWeight(); + + @ComProperty + void setWeight(XlBorderWeight weight); + + @ComProperty + XlLineStyle getLineStyle(); + + @ComProperty + void setLineStyle(XlLineStyle weight); +} diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/Chart.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/Chart.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/Chart.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/Chart.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,42 @@ +/* + * 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.COM.util.office.excel; + +import com.sun.jna.platform.win32.COM.IDispatch; +import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; +import com.sun.jna.platform.win32.COM.util.annotation.ComMethod; + +@ComInterface +public interface Chart { + @ComMethod + void ChartWizard(Object Source,Object Gallery,Object Format,Object PlotBy, + Object CategoryLabels,Object SeriesLabels,Object HasLegend, + Object Title,Object CategoryTitle,Object ValueTitle,Object ExtraTitle); + + @ComMethod + Series SeriesCollection(Object index); + + @ComMethod + IDispatch Location(XlChartLocation location, String name); +} diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/Charts.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/Charts.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/Charts.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/Charts.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,41 @@ +/* + * 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.COM.util.office.excel; + +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.ComProperty; + +@ComInterface +public interface Charts { + + @ComMethod + Chart Add(Object before, Object after, Object count, Object type); + + @ComProperty + int getCount(); + + @ComProperty + int getItem(Object item); +} diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComExcel_Application.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComExcel_Application.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComExcel_Application.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComExcel_Application.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,10 +1,33 @@ -package com.sun.jna.platform.win32.COM.util.office.excel; - -import com.sun.jna.platform.win32.COM.util.IUnknown; -import com.sun.jna.platform.win32.COM.util.annotation.ComMethod; -import com.sun.jna.platform.win32.COM.util.annotation.ComObject; - -@ComObject(progId="Excel.Application") -public interface ComExcel_Application extends IUnknown { - -} +/* + * 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.COM.util.office.excel; + +import com.sun.jna.platform.win32.COM.util.IUnknown; +import com.sun.jna.platform.win32.COM.util.annotation.ComMethod; +import com.sun.jna.platform.win32.COM.util.annotation.ComObject; + +@ComObject(progId="Excel.Application") +public interface ComExcel_Application extends IUnknown { + +} diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIAppEvents.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIAppEvents.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIAppEvents.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIAppEvents.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,12 +1,35 @@ -package com.sun.jna.platform.win32.COM.util.office.excel; - -import com.sun.jna.platform.win32.COM.util.annotation.ComEventCallback; -import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; - -@ComInterface(iid="{00024413-0000-0000-C000-000000000046}") -public interface ComIAppEvents { - - @ComEventCallback(dispid=1558) - public void SheetSelectionChange(ComIWorksheet sheet, ComIRange target); - -} +/* + * 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.COM.util.office.excel; + +import com.sun.jna.platform.win32.COM.util.annotation.ComEventCallback; +import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; + +@ComInterface(iid="{00024413-0000-0000-C000-000000000046}") +public interface ComIAppEvents { + + @ComEventCallback(dispid=1558) + public void SheetSelectionChange(ComIWorksheet sheet, ComIRange target); + +} diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIApplication.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIApplication.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIApplication.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIApplication.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,32 +1,61 @@ -package com.sun.jna.platform.win32.COM.util.office.excel; - -import com.sun.jna.platform.win32.COM.util.IConnectionPoint; -import com.sun.jna.platform.win32.COM.util.IUnknown; -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.ComProperty; - -@ComInterface(iid="{000208D5-0000-0000-C000-000000000046}") -public interface ComIApplication extends IUnknown, IConnectionPoint { - - @ComProperty - String getVersion(); - - @ComProperty - boolean getVisible(); - - @ComProperty - void setVisible(boolean value); - - @ComProperty - ComIWorkbooks getWorkbooks(); - - @ComProperty - ComIWorksheet getActiveSheet(); - - @ComProperty - ComIWorkbook getActiveWorkbook(); - - @ComMethod - void Quit(); -} +/* + * 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.COM.util.office.excel; + +import com.sun.jna.platform.win32.COM.util.IConnectionPoint; +import com.sun.jna.platform.win32.COM.util.IUnknown; +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.ComProperty; + +@ComInterface(iid="{000208D5-0000-0000-C000-000000000046}") +public interface ComIApplication extends IUnknown, IConnectionPoint { + + @ComProperty + String getVersion(); + + @ComProperty + boolean getVisible(); + + @ComProperty + void setVisible(boolean value); + + @ComProperty + ComIWorkbooks getWorkbooks(); + + @ComProperty + ComIWorksheet getActiveSheet(); + + @ComProperty + ComIWorkbook getActiveWorkbook(); + + @ComMethod + void Quit(); + + @ComProperty + boolean getUserControl(); + + @ComProperty + void setUserControl(boolean value); +} diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIRange.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIRange.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIRange.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIRange.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,25 +1,116 @@ -package com.sun.jna.platform.win32.COM.util.office.excel; - -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.ComProperty; - -@ComInterface(iid = "{00020846-0000-0000-C000-000000000046}") -public interface ComIRange { - - @ComProperty - ComIApplication getApplication(); - - @ComProperty - String getText(); - - @ComMethod - void Select(); - - @ComProperty - void setValue(String value); - - @ComMethod - void Activate(); - -} +/* + * 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.COM.util.office.excel; + +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.ComProperty; + +@ComInterface(iid = "{00020846-0000-0000-C000-000000000046}") +public interface ComIRange { + + @ComProperty + ComIApplication getApplication(); + + @ComProperty + String getText(); + + @ComMethod + void Select(); + + @ComProperty + void setValue(String value); + + @ComMethod + void Activate(); + + @ComProperty + ComIRange getItem(Object rowIndex, Object columnIndex); + + @ComProperty + void setValue(Object data); + + @ComProperty + Object getValue(); + + @ComProperty + void setFormula(String data); + + @ComProperty + String getFormula(); + + @ComProperty + void setNumberFormat(String data); + + @ComProperty + String getNumberFormat(); + + @ComProperty + ComIRange getEntireColumn(); + + @ComMethod + void AutoFit(); + + @ComProperty + public ComIRange getResize(Object rowSize, Object columnSize); + + @ComProperty + void setOrientation(int degree); + + @ComProperty + int getOrientation(); + + @ComProperty + void setWrapText(boolean wrap); + + @ComProperty + boolean getWrapText(); + + @ComProperty + Interior getInterior(); + + @ComProperty + Borders getBorders(); + + @ComProperty + int getTop(); + + @ComProperty + void setTop(int value); + + @ComProperty + int getLeft(); + + @ComProperty + void setLeft(int value); + + @ComProperty + String getName(); + + @ComProperty + void setName(String name); + + @ComProperty + void setAddress(String name); +} diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIWorkbook.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIWorkbook.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIWorkbook.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIWorkbook.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,13 +1,47 @@ -package com.sun.jna.platform.win32.COM.util.office.excel; - -import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; -import com.sun.jna.platform.win32.COM.util.annotation.ComMethod; - -@ComInterface(iid="{0002096B-0000-0000-C000-000000000046}") -public interface ComIWorkbook { - - @ComMethod - void Close(boolean saveChanges); - - -} +/* + * 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.COM.util.office.excel; + +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.ComProperty; + +@ComInterface(iid="{0002096B-0000-0000-C000-000000000046}") +public interface ComIWorkbook { + + @ComMethod + void Close(boolean saveChanges); + + @ComProperty + ComIWorksheet getActiveSheet(); + + @ComMethod + void Save(); + + @ComMethod + void SaveAs(String filename); + + @ComProperty + Charts getCharts(); +} diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIWorkbooks.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIWorkbooks.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIWorkbooks.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIWorkbooks.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,19 +1,44 @@ -package com.sun.jna.platform.win32.COM.util.office.excel; - -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.ComProperty; - -@ComInterface(iid = "{000208DB-0000-0000-C000-000000000046}") -public interface ComIWorkbooks { - - @ComProperty - long getCount(); - - @ComMethod - ComIWorkbook Item(long index); - - @ComMethod - ComIWorkbook Open(Object FileName); - -} +/* + * 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.COM.util.office.excel; + +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.ComProperty; + +@ComInterface(iid = "{000208DB-0000-0000-C000-000000000046}") +public interface ComIWorkbooks { + + @ComProperty + long getCount(); + + @ComMethod + ComIWorkbook Item(long index); + + @ComMethod + ComIWorkbook Open(Object FileName); + + @ComMethod + ComIWorkbook Add(); +} diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIWorksheet.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIWorksheet.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIWorksheet.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIWorksheet.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,19 +1,57 @@ -package com.sun.jna.platform.win32.COM.util.office.excel; - -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.ComProperty; - -@ComInterface(iid="{000208D8-0000-0000-C000-000000000046}") -public interface ComIWorksheet { - - @ComProperty - String getName(); - - @ComProperty - ComIRange getRange(String cell1); - - @ComProperty - ComIApplication getApplication(); - -} +/* + * 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.COM.util.office.excel; + +import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; +import com.sun.jna.platform.win32.COM.util.annotation.ComProperty; + +@ComInterface(iid="{000208D8-0000-0000-C000-000000000046}") +public interface ComIWorksheet { + @ComProperty + ComIWorkbook getParent(); + + @ComProperty + String getName(); + + @ComProperty + ComIRange getRange(String cell1); + + @ComProperty + ComIRange getRange(String cell1, String cell2); + + @ComProperty + ComIApplication getApplication(); + + @ComProperty + ComIRange getCells(); + + @ComProperty + Shapes getShapes(); + + @ComProperty + ComIRange getRows(Object identifier); + + @ComProperty + ComIRange getColumns(Object identifier); +} diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/Interior.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/Interior.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/Interior.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/Interior.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,36 @@ +/* + * 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.COM.util.office.excel; + +import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; +import com.sun.jna.platform.win32.COM.util.annotation.ComProperty; + +@ComInterface +public interface Interior { + @ComProperty + int getColorIndex(); + + @ComProperty + void setColorIndex(int value); +} diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/Series.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/Series.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/Series.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/Series.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,39 @@ +/* + * 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.COM.util.office.excel; + +import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; +import com.sun.jna.platform.win32.COM.util.annotation.ComProperty; + +@ComInterface +public interface Series { + @ComProperty + void setXValues(Object values); + + @ComProperty + String getName(); + + @ComProperty + void setName(String name); +} diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/Shape.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/Shape.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/Shape.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/Shape.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,44 @@ +/* + * 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.COM.util.office.excel; + +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.ComProperty; + +@ComInterface +public interface Shape { + + @ComProperty + int getTop(); + + @ComProperty + void setTop(int value); + + @ComProperty + int getLeft(); + + @ComProperty + void setLeft(int value); +} diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/Shapes.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/Shapes.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/Shapes.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/Shapes.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,33 @@ +/* + * 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.COM.util.office.excel; + +import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; +import com.sun.jna.platform.win32.COM.util.annotation.ComMethod; + +@ComInterface +public interface Shapes { + @ComMethod + Shape Item(Object index); +} diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/XlBorderWeight.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/XlBorderWeight.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/XlBorderWeight.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/XlBorderWeight.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,44 @@ +/* + * 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.COM.util.office.excel; + +import com.sun.jna.platform.win32.COM.util.office.word.*; +import com.sun.jna.platform.win32.COM.util.IComEnum; + +public enum XlBorderWeight implements IComEnum { + + xlHairline(1), + xlMedium(-4138), + xlThick(4), + xlThin(2); + + private XlBorderWeight(long value) { + this.value = value; + } + private long value; + + public long getValue() { + return this.value; + } +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/XlChartLocation.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/XlChartLocation.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/XlChartLocation.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/XlChartLocation.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,43 @@ +/* + * 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.COM.util.office.excel; + +import com.sun.jna.platform.win32.COM.util.office.word.*; +import com.sun.jna.platform.win32.COM.util.IComEnum; + +public enum XlChartLocation implements IComEnum { + + xlLocationAsNewSheet(1), + xlLocationAsObject(2), + xlLocationAutomatic(3); + + private XlChartLocation(long value) { + this.value = value; + } + private long value; + + public long getValue() { + return this.value; + } +} diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/XlChartType.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/XlChartType.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/XlChartType.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/XlChartType.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,113 @@ +/* + * 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.COM.util.office.excel; + +import com.sun.jna.platform.win32.COM.util.office.word.*; +import com.sun.jna.platform.win32.COM.util.IComEnum; + +public enum XlChartType implements IComEnum { + + xlColumnClustered(51), + xlColumnStacked(52), + xlColumnStacked100(53), + xl3DColumnClustered(54), + xl3DColumnStacked(55), + xl3DColumnStacked100(56), + xlBarClustered(57), + xlBarStacked(58), + xlBarStacked100(59), + xl3DBarClustered(60), + xl3DBarStacked(61), + xl3DBarStacked100(62), + xlLineStacked(63), + xlLineStacked100(64), + xlLineMarkers(65), + xlLineMarkersStacked(66), + xlLineMarkersStacked100(67), + xlPieOfPie(68), + xlPieExploded(69), + xl3DPieExploded(70), + xlBarOfPie(71), + xlXYScatterSmooth(72), + xlXYScatterSmoothNoMarkers(73), + xlXYScatterLines(74), + xlXYScatterLinesNoMarkers(75), + xlAreaStacked(76), + xlAreaStacked100(77), + xl3DAreaStacked(78), + xl3DAreaStacked100(79), + xlDoughnutExploded(80), + xlRadarMarkers(81), + xlRadarFilled(82), + xlSurface(83), + xlSurfaceWireframe(84), + xlSurfaceTopView(85), + xlSurfaceTopViewWireframe(86), + xlBubble(15), + xlBubble3DEffect(87), + xlStockHLC(88), + xlStockOHLC(89), + xlStockVHLC(90), + xlStockVOHLC(91), + xlCylinderColClustered(92), + xlCylinderColStacked(93), + xlCylinderColStacked100(94), + xlCylinderBarClustered(95), + xlCylinderBarStacked(96), + xlCylinderBarStacked100(97), + xlCylinderCol(98), + xlConeColClustered(99), + xlConeColStacked(100), + xlConeColStacked100(101), + xlConeBarClustered(102), + xlConeBarStacked(103), + xlConeBarStacked100(104), + xlConeCol(105), + xlPyramidColClustered(106), + xlPyramidColStacked(107), + xlPyramidColStacked100(108), + xlPyramidBarClustered(109), + xlPyramidBarStacked(110), + xlPyramidBarStacked100(111), + xlPyramidCol(112), + xl3DColumn(-4100), + xlLine(4), + xl3DLine(-4101), + xl3DPie(-4102), + xlPie(5), + xlXYScatter(-4169), + xl3DArea(-4098), + xlArea(1), + xlDoughnut(-4120), + xlRadar(-4151); + + private XlChartType(long value) { + this.value = value; + } + private long value; + + public long getValue() { + return this.value; + } +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/XlLineStyle.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/XlLineStyle.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/XlLineStyle.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/XlLineStyle.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,48 @@ +/* + * 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.COM.util.office.excel; + +import com.sun.jna.platform.win32.COM.util.office.word.*; +import com.sun.jna.platform.win32.COM.util.IComEnum; + +public enum XlLineStyle implements IComEnum { + + xlContinuous(1), + xlDash(-4115), + xlDashDot(4), + xlDashDotDot(5), + xlDot(-4118), + xlDouble(-4119), + xlSlantDashDot(13), + xlLineStyleNone(-4142); + + private XlLineStyle(long value) { + this.value = value; + } + private long value; + + public long getValue() { + return this.value; + } +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/XlRowCol.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/XlRowCol.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/XlRowCol.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/XlRowCol.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,42 @@ +/* + * 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.COM.util.office.excel; + +import com.sun.jna.platform.win32.COM.util.office.word.*; +import com.sun.jna.platform.win32.COM.util.IComEnum; + +public enum XlRowCol implements IComEnum { + + xlColumns(2), + xlRows(1); + + private XlRowCol(long value) { + this.value = value; + } + private long value; + + public long getValue() { + return this.value; + } +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/Excelautomation_KB_219151_Mod.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/Excelautomation_KB_219151_Mod.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/Excelautomation_KB_219151_Mod.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/Excelautomation_KB_219151_Mod.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,224 @@ +/* + * 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.COM.util.office; + +import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.COM.Helper; +import com.sun.jna.platform.win32.COM.util.Factory; +import com.sun.jna.platform.win32.COM.util.office.excel.Borders; +import com.sun.jna.platform.win32.COM.util.office.excel.Chart; +import com.sun.jna.platform.win32.COM.util.office.excel.ComExcel_Application; +import com.sun.jna.platform.win32.COM.util.office.excel.ComIApplication; +import com.sun.jna.platform.win32.COM.util.office.excel.ComIRange; +import com.sun.jna.platform.win32.COM.util.office.excel.ComIWorkbook; +import com.sun.jna.platform.win32.COM.util.office.excel.ComIWorksheet; +import com.sun.jna.platform.win32.COM.util.office.excel.Shape; +import com.sun.jna.platform.win32.COM.util.office.excel.XlBorderWeight; +import com.sun.jna.platform.win32.COM.util.office.excel.XlChartLocation; +import com.sun.jna.platform.win32.COM.util.office.excel.XlLineStyle; +import com.sun.jna.platform.win32.COM.util.office.excel.XlRowCol; +import com.sun.jna.platform.win32.COM.util.office.office.XlChartType; +import com.sun.jna.platform.win32.OaIdl; +import com.sun.jna.platform.win32.OaIdl.SAFEARRAY; +import com.sun.jna.platform.win32.Ole32; +import com.sun.jna.platform.win32.Variant; +import com.sun.jna.platform.win32.Variant.VARIANT; +import static com.sun.jna.platform.win32.Variant.VARIANT.VARIANT_MISSING; +import com.sun.jna.platform.win32.WTypes.BSTR; +import com.sun.jna.platform.win32.WinDef.LCID; +import java.io.File; + +import java.io.IOException; +import javax.swing.JDialog; + +import javax.swing.JOptionPane; + +/** + * Based on VB sample: https://support.microsoft.com/en-us/kb/219151 + * + *

Please note: The contained type-bindings are far from complete and only + * included as sample - please use one of the generators to generate complete + * bindings or enhance the coverage yourself.

+ */ +public class Excelautomation_KB_219151_Mod { + + public static void main(String[] args) throws IOException { + // Initialize COM Subsystem + Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED); + // Initialize Factory for COM object creation + Factory fact = new Factory(); + // Set LCID for calls to english locale. Without this formulas need + // to be specified in the users locale. + fact.setLCID(new LCID(0x0409)); + + try { + // Start excel application + ComExcel_Application excel = fact.createObject(ComExcel_Application.class); + ComIApplication excelApp = excel.queryInterface(ComIApplication.class); + + // Set visiblite of application + excelApp.setVisible(true); + + Helper.sleep(5); + + // Get a new workbook. + ComIWorkbook wb = excelApp.getWorkbooks().Add(); + ComIWorksheet sheet = wb.getActiveSheet(); + + // Add table headers going cell by cell. + sheet.getCells().getItem(1, 1).setValue("First Name"); + sheet.getCells().getItem(1, 2).setValue("Last Name"); + sheet.getCells().getItem(1, 3).setValue("Full Name"); + sheet.getCells().getItem(1, 4).setValue("Salary"); + + // Create an array to set multiple values at once. + SAFEARRAY saNames = safeVariantArrayFromJava(new String[][] { + {"John", "Smith"}, + {"Tom", "Brown"}, + {"Sue", "Thomas"}, + {"Jane", "Jones"}, + {"Adam", "Johnson"}, + }); + + // Fill A2:B6 with an array of values (First and Last Names). + VARIANT valueHolder = new VARIANT(); + valueHolder.setValue(Variant.VT_ARRAY | Variant.VT_VARIANT, saNames); + sheet.getRange("A2", "B6").setValue(valueHolder); + saNames.destroy(); + + // Fill C2:C6 with a relative formula (=A2 & " " & B2). + sheet.getRange("C2", "C6").setFormula("= A2 & \" \" & B2"); + + // Fill D2:D6 with a formula(=RAND()*100000) and apply format. + sheet.getRange("D2", "D6").setFormula("=RAND()*100000"); + sheet.getRange("D2", "D6").setNumberFormat("$0.00"); + + // AutoFit columns A:D. + sheet.getRange("A1", "D2").getEntireColumn().AutoFit(); + + displayQuaterlySales(sheet); + + File tempFile = Helper.createNotExistingFile("exceloutput", ".xlsx"); + System.out.println("Writing output to: " + tempFile.getAbsolutePath()); + wb.SaveAs(tempFile.getAbsolutePath()); + + excelApp.setUserControl(true); + } finally { + fact.disposeAll(); + Ole32.INSTANCE.CoUninitialize(); + } + + System.exit(0); + } + + private static void displayQuaterlySales(ComIWorksheet sheet) { + // Determine how many quarters to display data for. + int iNumQtrs = 4; + for(; iNumQtrs >= 2; iNumQtrs--) { + JOptionPane pane = new JOptionPane( + String.format("Enter sales data for %d quarter(s)?", iNumQtrs), + JOptionPane.QUESTION_MESSAGE); + pane.setOptionType(JOptionPane.YES_NO_OPTION); + JDialog dialog = pane.createDialog("Input..."); + dialog.setAlwaysOnTop(true); + dialog.show(); + if(((Integer) pane.getValue()) == JOptionPane.YES_OPTION) { + break; + } + } + + JOptionPane.showMessageDialog( + null, + String.format("Displaying data for %d quarter(s).", iNumQtrs) + ); + + // Starting at E1, fill headers for the number of columns selected. + ComIRange oResizeRange = sheet.getRange("E1", "E1").getResize(VARIANT_MISSING, iNumQtrs); + + oResizeRange.setFormula("=\"Q\" & COLUMN() - 4 & CHAR(10) & \"Sales\""); + + // Change the Orientation and WrapText properties for the headers. + oResizeRange.setOrientation(38); + oResizeRange.setWrapText(true); + + // Fill the interior color of the headers. + oResizeRange.getInterior().setColorIndex(36); + + // Fill the columns with a formula and apply a number format. + oResizeRange = sheet.getRange("E2", "E6").getResize(VARIANT_MISSING, iNumQtrs); + oResizeRange.setFormula("=RAND()*100"); + oResizeRange.setNumberFormat("$0.00"); + + // Apply borders to the Sales data and headers. + oResizeRange = sheet.getRange("E1", "E6").getResize(VARIANT_MISSING, iNumQtrs); + oResizeRange.getBorders().setWeight(XlBorderWeight.xlThin); + + // Add a Totals formula for the sales data and apply a border. + oResizeRange = sheet.getRange("E8", "E8").getResize(VARIANT_MISSING, iNumQtrs); + oResizeRange.setFormula("=SUM(E2:E6)"); + Borders oResizeRangeBorders = oResizeRange.getBorders(); + oResizeRangeBorders.setLineStyle(XlLineStyle.xlDouble); + oResizeRangeBorders.setWeight(XlBorderWeight.xlThick); + + // Add a Chart for the selected data + oResizeRange = sheet.getRange("E2:E6").getResize(VARIANT_MISSING, iNumQtrs); + + Chart chart = sheet.getParent().getCharts().Add(VARIANT_MISSING,VARIANT_MISSING,VARIANT_MISSING,VARIANT_MISSING); + // Java note: Assumption is, that VARIANT_MISSING is the correct indicator + // for missing values, it turns out, NULL is correct in this case... + chart.ChartWizard(oResizeRange, XlChartType.xl3DColumn, VARIANT_MISSING, + XlRowCol.xlColumns, + null, null, null, + null,null,null, + null + ); + chart.SeriesCollection(1).setXValues(sheet.getRange("C2", "C6")); + for(int i = 1; i <= iNumQtrs; i++) { + chart.SeriesCollection(i).setName("=\"Q" + Integer.toString(i) + "\""); + } + chart.Location(XlChartLocation.xlLocationAsObject, sheet.getName()); + + // Move the chart so as not to cover your data. + Shape shape = sheet.getShapes().Item(1); + shape.setTop(sheet.getRows(10).getTop()); + shape.setLeft(sheet.getColumns(2).getLeft()); + } + + private static SAFEARRAY safeVariantArrayFromJava(String[][] data) { + // The data array is defined/stored row major, while excel expects the + // data column major, so this method also transposes the matrix + + OaIdl.SAFEARRAY wrapped = OaIdl.SAFEARRAY.createSafeArray(data[0].length, data.length); + // VARIANT is java allocated and will be freed by GC + VARIANT var = new VARIANT(); + for(int i = 0; i < data.length; i++) { + for(int j = 0; j < data[0].length; j++) { + // BSTR is allocated by java and will be freed by GC + var.setValue(Variant.VT_BSTR, new BSTR(data[i][j])); + wrapped.putElement(var, j, i); + } + } + return wrapped; + } +} diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/MSOfficeExcelDemo.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/MSOfficeExcelDemo.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/MSOfficeExcelDemo.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/MSOfficeExcelDemo.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,68 +1,91 @@ /* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM.util.office; +import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.COM.Helper; import java.io.File; -import com.sun.jna.platform.win32.COM.office.MSExcel; import com.sun.jna.platform.win32.COM.util.AbstractComEventCallbackListener; import com.sun.jna.platform.win32.COM.util.Factory; +import com.sun.jna.platform.win32.COM.util.IComEventCallbackCookie; import com.sun.jna.platform.win32.COM.util.office.excel.ComExcel_Application; import com.sun.jna.platform.win32.COM.util.office.excel.ComIAppEvents; import com.sun.jna.platform.win32.COM.util.office.excel.ComIApplication; import com.sun.jna.platform.win32.COM.util.office.excel.ComIRange; +import com.sun.jna.platform.win32.COM.util.office.excel.ComIWorkbook; import com.sun.jna.platform.win32.COM.util.office.excel.ComIWorksheet; -import com.sun.jna.platform.win32.COM.util.office.word.ComWord_Application; +import com.sun.jna.platform.win32.Ole32; +import java.io.IOException; public class MSOfficeExcelDemo { + private static final String currentWorkingDir = new File("").getAbsolutePath() + File.separator; - /** - * @param args - */ - public static void main(String[] args) { - new MSOfficeExcelDemo(); - } - - private String currentWorkingDir = new File("").getAbsolutePath() + File.separator; - - public MSOfficeExcelDemo() { - this.testMSExcel(); - } - - public void testMSExcel() { - ComExcel_Application excelObject = null; - ComIApplication msExcel = null; - Factory factory = null; + public static void main(String[] argv) throws IOException { + Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED); + try { + testExcel(); + } finally { + Ole32.INSTANCE.CoUninitialize(); + } + } + + public static void testExcel() throws IOException { + File demoDocument = null; + ComIApplication msExcel = null; + Factory factory = new Factory(); try { - factory = new Factory(); - excelObject = factory.createObject(ComExcel_Application.class); + System.out.println("Files in temp dir: " + Helper.tempDir.getAbsolutePath()); + + ComExcel_Application excelObject = factory.createObject(ComExcel_Application.class); msExcel = excelObject.queryInterface(ComIApplication.class); + System.out.println("MSExcel version: " + msExcel.getVersion()); + msExcel.setVisible(true); - // msExcel.newExcelBook(); - msExcel.getWorkbooks().Open(currentWorkingDir + "jnatest.xls"); + + Helper.sleep(5); + + demoDocument = Helper.createNotExistingFile("jnatest", ".xls"); + Helper.extractClasspathFileToReal("/com/sun/jna/platform/win32/COM/util/office/resources/jnatest.xls", demoDocument); + + ComIWorkbook workbook = msExcel.getWorkbooks().Open(demoDocument.getAbsolutePath()); msExcel.getActiveSheet().getRange("A1").setValue("Hello from JNA!"); // wait 1sec. before closing - Thread.currentThread().sleep(1000); -// // close and save the active sheet -// msExcel.getActiveWorkbook().Close(true); -// msExcel.setVisible(true); + Helper.sleep(1); + // Save document into temp and close + File output = new File(Helper.tempDir, "jnatest.xls"); + output.delete(); + workbook.SaveAs(output.getAbsolutePath()); + msExcel.getActiveWorkbook().Close(false); + // // msExcel.newExcelBook(); -// msExcel.getWorkbooks().Open(currentWorkingDir + "jnatest.xls"); -// msExcel.getActiveSheet().getRange("A2").setValue("Hello again from JNA!"); + msExcel.getWorkbooks().Open(output.getAbsolutePath()); + msExcel.getActiveSheet().getRange("A2").setValue("Hello again from JNA!"); class Listener extends AbstractComEventCallbackListener implements ComIAppEvents { - boolean SheetSelectionChange_called; + volatile boolean SheetSelectionChange_called; @Override public void errorReceivingCallbackEvent(String message, Exception exception) { @@ -75,26 +98,32 @@ }; Listener listener = new Listener(); - msExcel.advise(ComIAppEvents.class, listener); -// -// msExcel.getActiveSheet().getRange("A5").Activate(); -// -// Thread.currentThread().sleep(500); + IComEventCallbackCookie cookie = msExcel.advise(ComIAppEvents.class, listener); - // close and save the active sheet - msExcel.getActiveWorkbook().Close(true); + Helper.sleep(1); + + msExcel.getActiveSheet().getRange("A5").Activate(); - msExcel.Quit(); - msExcel = null; - } catch (Exception e) { - e.printStackTrace(); + Helper.sleep(1); + + msExcel.unadvise(ComIAppEvents.class, cookie); + + System.out.println("Listener was fired: " + listener.SheetSelectionChange_called); + + // close and discard changes + msExcel.getActiveWorkbook().Close(false); } finally { + // Make sure the excel instance is shut down if (null != msExcel) { msExcel.Quit(); } - if (null != factory) { - factory.disposeAll(); - } + + // Release all objects acquired by the factory + factory.disposeAll(); + + if (demoDocument != null && demoDocument.exists()) { + demoDocument.delete(); + } } } } diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/MSOfficeWordDemo.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/MSOfficeWordDemo.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/MSOfficeWordDemo.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/MSOfficeWordDemo.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,109 +1,122 @@ /* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM.util.office; import java.io.File; -import com.sun.jna.platform.win32.COM.COMException; +import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.Ole32; +import com.sun.jna.platform.win32.COM.Helper; import com.sun.jna.platform.win32.COM.util.Factory; import com.sun.jna.platform.win32.COM.util.office.word.ComIApplication; import com.sun.jna.platform.win32.COM.util.office.word.ComWord_Application; import com.sun.jna.platform.win32.COM.util.office.word.WdOriginalFormat; import com.sun.jna.platform.win32.COM.util.office.word.WdSaveFormat; +import java.io.IOException; public class MSOfficeWordDemo { + private static final String currentWorkingDir = new File("").getAbsolutePath() + File.separator; - /** - * @param args - */ - public static void main(String[] args) { - new MSOfficeWordDemo(); + public static void main(String[] args) throws IOException { + Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED); + try { + testMSWord(); + } finally { + Ole32.INSTANCE.CoUninitialize(); + } } - private String currentWorkingDir = new File("").getAbsolutePath() + File.separator; - - public MSOfficeWordDemo() { - this.testMSWord(); - } - - public void testMSWord() { - ComWord_Application msWordObject = null; + public static void testMSWord() throws IOException { + File demoDocument = null; ComIApplication msWord = null; - Factory factory = null; + Factory factory = new Factory(); + try { - String tempDir = System.getProperty("java.io.tmpdir"); - System.out.println("Files in temp dir: "+tempDir); - - factory = new Factory(); - msWordObject = factory.createObject(ComWord_Application.class); + System.out.println("Files in temp dir: " + Helper.tempDir.getAbsolutePath()); + + ComWord_Application msWordObject = factory.createObject(ComWord_Application.class); msWord = msWordObject.queryInterface(ComIApplication.class); System.out.println("MSWord version: " + msWord.getVersion()); msWord.setVisible(true); - // msWord.newDocument(); - msWord.getDocuments().Open(currentWorkingDir + "jnatest.doc"); + + demoDocument = Helper.createNotExistingFile("jnatest", ".doc"); + Helper.extractClasspathFileToReal("/com/sun/jna/platform/win32/COM/util/office/resources/jnatest.doc", demoDocument); + + msWord.getDocuments().Open(demoDocument.getAbsolutePath()); + + Helper.sleep(5); + msWord.getSelection().TypeText("Hello from JNA! \n\n"); // wait 10sec. before closing - Thread.sleep(1000); + Helper.sleep(10); // save in different formats // pdf format is only supported in MSWord 2007 and above - msWord.getActiveDocument().SaveAs(tempDir+"\\jnatestSaveAs.doc", WdSaveFormat.wdFormatDocument); - msWord.getActiveDocument().SaveAs(tempDir+"\\jnatestSaveAs.pdf", WdSaveFormat.wdFormatPDF); - msWord.getActiveDocument().SaveAs(tempDir+"\\jnatestSaveAs.rtf", WdSaveFormat.wdFormatRTF); - msWord.getActiveDocument().SaveAs(tempDir+"\\jnatestSaveAs.html", WdSaveFormat.wdFormatHTML); - // close and save the document + msWord.getActiveDocument().SaveAs(new File(Helper.tempDir, "jnatestSaveAs.doc").getAbsolutePath(), WdSaveFormat.wdFormatDocument); + msWord.getActiveDocument().SaveAs(new File(Helper.tempDir, "jnatestSaveAs.pdf").getAbsolutePath(), WdSaveFormat.wdFormatPDF); + msWord.getActiveDocument().SaveAs(new File(Helper.tempDir, "jnatestSaveAs.rtf").getAbsolutePath(), WdSaveFormat.wdFormatRTF); + msWord.getActiveDocument().SaveAs(new File(Helper.tempDir, "jnatestSaveAs.html").getAbsolutePath(), WdSaveFormat.wdFormatHTML); + // close and don't save the changes msWord.getActiveDocument().Close(false); + + // Create a new document msWord.getDocuments().Add(); // msWord.openDocument(currentWorkingDir + "jnatest.doc", true); - msWord.getSelection() - .TypeText( - "Hello from JNA! \n Please notice that JNA can control MS Word via the new COM interface! \nHere we are creating a new word document and we save it to the 'TEMP' directory!"); - // save with no user prompt - msWord.getActiveDocument().SaveAs(tempDir+"\\jnatestNewDoc1.docx", WdSaveFormat.wdFormatDocumentDefault); - msWord.getActiveDocument().SaveAs(tempDir+"\\jnatestNewDoc2.docx", WdSaveFormat.wdFormatDocumentDefault); - msWord.getActiveDocument().SaveAs(tempDir+"\\jnatestNewDoc3.docx", WdSaveFormat.wdFormatDocumentDefault); - // close and save the document + msWord.getSelection().TypeText( + "Hello from JNA! \n Please notice that JNA can control " + + "MS Word via the new COM interface! \nHere we are " + + "creating a new word document and we save it " + + "to the 'TEMP' directory!"); + // save with no user prompt + msWord.getActiveDocument().SaveAs(new File(Helper.tempDir, "jnatestNewDoc1.docx").getAbsolutePath(), WdSaveFormat.wdFormatDocumentDefault); + msWord.getActiveDocument().SaveAs(new File(Helper.tempDir, "jnatestNewDoc2.docx").getAbsolutePath(), WdSaveFormat.wdFormatDocumentDefault); + msWord.getActiveDocument().SaveAs(new File(Helper.tempDir, "jnatestNewDoc3.docx").getAbsolutePath(), WdSaveFormat.wdFormatDocumentDefault); + // close and don't save the changes msWord.getActiveDocument().Close(false); + // open 3 documents - msWord.getDocuments().Open(tempDir+"\\jnatestNewDoc1.docx"); + msWord.getDocuments().Open(new File(Helper.tempDir, "jnatestNewDoc1.docx").getAbsolutePath()); msWord.getSelection().TypeText("Hello some changes from JNA!\n"); - msWord.getDocuments().Open(tempDir+"\\jnatestNewDoc2.docx"); + msWord.getDocuments().Open(new File(Helper.tempDir, "jnatestNewDoc2.docx").getAbsolutePath()); msWord.getSelection().TypeText("Hello some changes from JNA!\n"); - msWord.getDocuments().Open(tempDir+"\\jnatestNewDoc3.docx"); + msWord.getDocuments().Open(new File(Helper.tempDir, "jnatestNewDoc3.docx").getAbsolutePath()); msWord.getSelection().TypeText("Hello some changes from JNA!\n"); // save the document and prompt the user msWord.getDocuments().Save(false, WdOriginalFormat.wdPromptUser); - // wait then close word - msWord.Quit(); - msWord = null; - } catch (InterruptedException ie) { - ie.printStackTrace(); - } catch (COMException e) { - if (e.getExcepInfo() != null) { - System.out.println("bstrSource: " + e.getExcepInfo().bstrSource); - System.out.println("bstrDescription: " + e.getExcepInfo().bstrDescription); - } - - // print stack trace - e.printStackTrace(); } finally { + // Make sure the word instance is shut down if (msWord != null) { msWord.Quit(); } - if (null != factory) { - factory.getComThread().terminate(500); - } + + // Release all objects acquired by the factory + factory.disposeAll(); + + if (demoDocument != null && demoDocument.exists()) { + demoDocument.delete(); + } } } } diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/office/XlChartType.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/office/XlChartType.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/office/XlChartType.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/office/XlChartType.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,434 @@ +/* + * 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.COM.util.office.office; + +import com.sun.jna.platform.win32.COM.util.IComEnum; + +public enum XlChartType implements IComEnum { + + /** + * (51) + */ + xlColumnClustered(51), + + /** + * (52) + */ + xlColumnStacked(52), + + /** + * (53) + */ + xlColumnStacked100(53), + + /** + * (54) + */ + xl3DColumnClustered(54), + + /** + * (55) + */ + xl3DColumnStacked(55), + + /** + * (56) + */ + xl3DColumnStacked100(56), + + /** + * (57) + */ + xlBarClustered(57), + + /** + * (58) + */ + xlBarStacked(58), + + /** + * (59) + */ + xlBarStacked100(59), + + /** + * (60) + */ + xl3DBarClustered(60), + + /** + * (61) + */ + xl3DBarStacked(61), + + /** + * (62) + */ + xl3DBarStacked100(62), + + /** + * (63) + */ + xlLineStacked(63), + + /** + * (64) + */ + xlLineStacked100(64), + + /** + * (65) + */ + xlLineMarkers(65), + + /** + * (66) + */ + xlLineMarkersStacked(66), + + /** + * (67) + */ + xlLineMarkersStacked100(67), + + /** + * (68) + */ + xlPieOfPie(68), + + /** + * (69) + */ + xlPieExploded(69), + + /** + * (70) + */ + xl3DPieExploded(70), + + /** + * (71) + */ + xlBarOfPie(71), + + /** + * (72) + */ + xlXYScatterSmooth(72), + + /** + * (73) + */ + xlXYScatterSmoothNoMarkers(73), + + /** + * (74) + */ + xlXYScatterLines(74), + + /** + * (75) + */ + xlXYScatterLinesNoMarkers(75), + + /** + * (76) + */ + xlAreaStacked(76), + + /** + * (77) + */ + xlAreaStacked100(77), + + /** + * (78) + */ + xl3DAreaStacked(78), + + /** + * (79) + */ + xl3DAreaStacked100(79), + + /** + * (80) + */ + xlDoughnutExploded(80), + + /** + * (81) + */ + xlRadarMarkers(81), + + /** + * (82) + */ + xlRadarFilled(82), + + /** + * (83) + */ + xlSurface(83), + + /** + * (84) + */ + xlSurfaceWireframe(84), + + /** + * (85) + */ + xlSurfaceTopView(85), + + /** + * (86) + */ + xlSurfaceTopViewWireframe(86), + + /** + * (15) + */ + xlBubble(15), + + /** + * (87) + */ + xlBubble3DEffect(87), + + /** + * (88) + */ + xlStockHLC(88), + + /** + * (89) + */ + xlStockOHLC(89), + + /** + * (90) + */ + xlStockVHLC(90), + + /** + * (91) + */ + xlStockVOHLC(91), + + /** + * (92) + */ + xlCylinderColClustered(92), + + /** + * (93) + */ + xlCylinderColStacked(93), + + /** + * (94) + */ + xlCylinderColStacked100(94), + + /** + * (95) + */ + xlCylinderBarClustered(95), + + /** + * (96) + */ + xlCylinderBarStacked(96), + + /** + * (97) + */ + xlCylinderBarStacked100(97), + + /** + * (98) + */ + xlCylinderCol(98), + + /** + * (99) + */ + xlConeColClustered(99), + + /** + * (100) + */ + xlConeColStacked(100), + + /** + * (101) + */ + xlConeColStacked100(101), + + /** + * (102) + */ + xlConeBarClustered(102), + + /** + * (103) + */ + xlConeBarStacked(103), + + /** + * (104) + */ + xlConeBarStacked100(104), + + /** + * (105) + */ + xlConeCol(105), + + /** + * (106) + */ + xlPyramidColClustered(106), + + /** + * (107) + */ + xlPyramidColStacked(107), + + /** + * (108) + */ + xlPyramidColStacked100(108), + + /** + * (109) + */ + xlPyramidBarClustered(109), + + /** + * (110) + */ + xlPyramidBarStacked(110), + + /** + * (111) + */ + xlPyramidBarStacked100(111), + + /** + * (112) + */ + xlPyramidCol(112), + + /** + * (-4100) + */ + xl3DColumn(-4100), + + /** + * (4) + */ + xlLine(4), + + /** + * (-4101) + */ + xl3DLine(-4101), + + /** + * (-4102) + */ + xl3DPie(-4102), + + /** + * (5) + */ + xlPie(5), + + /** + * (-4169) + */ + xlXYScatter(-4169), + + /** + * (-4098) + */ + xl3DArea(-4098), + + /** + * (1) + */ + xlArea(1), + + /** + * (-4120) + */ + xlDoughnut(-4120), + + /** + * (-4151) + */ + xlRadar(-4151), + + /** + * (-4152) + */ + xlCombo(-4152), + + /** + * (113) + */ + xlComboColumnClusteredLine(113), + + /** + * (114) + */ + xlComboColumnClusteredLineSecondaryAxis(114), + + /** + * (115) + */ + xlComboAreaStackedColumnClustered(115), + + /** + * (116) + */ + xlOtherCombinations(116), + + /** + * (-2) + */ + xlSuggestedChart(-2), + ; + + private XlChartType(long value) { + this.value = value; + } + private long value; + + public long getValue() { + return this.value; + } +} \ No newline at end of file Binary files /tmp/tmptdXlQx/zXsTgf0UHo/libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/resources/jnatest.doc and /tmp/tmptdXlQx/nhswvPAIcW/libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/resources/jnatest.doc differ Binary files /tmp/tmptdXlQx/zXsTgf0UHo/libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/resources/jnatest.xls and /tmp/tmptdXlQx/nhswvPAIcW/libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/resources/jnatest.xls differ diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Bookmark.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Bookmark.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Bookmark.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Bookmark.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,116 @@ +/* + * 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.COM.util.office.word; + +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.ComProperty; +import com.sun.jna.platform.win32.COM.util.IDispatch; +import com.sun.jna.platform.win32.Variant.VARIANT; + +/** + *

uuid({00020968-0000-0000-C000-000000000046})

+ */ +@ComInterface(iid="{00020968-0000-0000-C000-000000000046}") +public interface Bookmark { + /** + *

id(0x0)

+ */ + @ComProperty(name = "Name", dispId = 0x0) + String getName(); + + /** + *

id(0x1)

+ */ + @ComProperty(name = "Range", dispId = 0x1) + Range getRange(); + + /** + *

id(0x2)

+ */ + @ComProperty(name = "Empty", dispId = 0x2) + Boolean getEmpty(); + + /** + *

id(0x3)

+ */ + @ComProperty(name = "Start", dispId = 0x3) + Integer getStart(); + + /** + *

id(0x3)

+ */ + @ComProperty(name = "Start", dispId = 0x3) + void setStart(Integer param0); + + /** + *

id(0x4)

+ */ + @ComProperty(name = "End", dispId = 0x4) + Integer getEnd(); + + /** + *

id(0x4)

+ */ + @ComProperty(name = "End", dispId = 0x4) + void setEnd(Integer param0); + + /** + *

id(0x5)

+ */ + @ComProperty(name = "Column", dispId = 0x5) + Boolean getColumn(); + + /** + *

id(0x3e9)

+ */ + @ComProperty(name = "Creator", dispId = 0x3e9) + Integer getCreator(); + + /** + *

id(0x3ea)

+ */ + @ComProperty(name = "Parent", dispId = 0x3ea) + com.sun.jna.platform.win32.COM.util.IDispatch getParent(); + + /** + *

id(0xffff)

+ */ + @ComMethod(name = "Select", dispId = 0xffff) + void Select(); + + /** + *

id(0xb)

+ */ + @ComMethod(name = "Delete", dispId = 0xb) + void Delete(); + + /** + *

id(0xc)

+ */ + @ComMethod(name = "Copy", dispId = 0xc) + Bookmark Copy(String Name); + + +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Bookmarks.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Bookmarks.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Bookmarks.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Bookmarks.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,50 @@ +/* + * 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.COM.util.office.word; + +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.ComProperty; +import com.sun.jna.platform.win32.COM.util.IDispatch; +import com.sun.jna.platform.win32.Variant.VARIANT; + +/** + *

uuid({00020967-0000-0000-C000-000000000046})

+ */ +@ComInterface(iid="{00020967-0000-0000-C000-000000000046}") +public interface Bookmarks { + /** + *

id(0x2)

+ */ + @ComProperty(name = "Count", dispId = 0x2) + Integer getCount(); + + /** + *

id(0x0)

+ */ + @ComMethod(name = "Item", dispId = 0x0) + Bookmark Item(Object Index); + + +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Cell.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Cell.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Cell.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Cell.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,42 @@ +/* + * 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.COM.util.office.word; + +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.ComProperty; +import com.sun.jna.platform.win32.COM.util.IDispatch; +import com.sun.jna.platform.win32.Variant.VARIANT; + +/** + *

uuid({0002094E-0000-0000-C000-000000000046})

+ */ +@ComInterface(iid="{0002094E-0000-0000-C000-000000000046}") +public interface Cell { + /** + *

id(0x0)

+ */ + @ComProperty(name = "Range", dispId = 0x0) + Range getRange(); +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Column.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Column.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Column.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Column.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,48 @@ +/* + * 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.COM.util.office.word; + +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.ComProperty; +import com.sun.jna.platform.win32.COM.util.IDispatch; +import com.sun.jna.platform.win32.Variant.VARIANT; + +/** + *

uuid({0002094F-0000-0000-C000-000000000046})

+ */ +@ComInterface(iid="{0002094F-0000-0000-C000-000000000046}") +public interface Column { + /** + *

id(0x3)

+ */ + @ComProperty(name = "Width", dispId = 0x3) + Float getWidth(); + + /** + *

id(0x3)

+ */ + @ComProperty(name = "Width", dispId = 0x3) + void setWidth(Float param0); +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Columns.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Columns.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Columns.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Columns.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,59 @@ +/* + * 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.COM.util.office.word; + +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.ComProperty; +import com.sun.jna.platform.win32.COM.util.IDispatch; +import com.sun.jna.platform.win32.Variant.VARIANT; + +/** + *

uuid({0002094B-0000-0000-C000-000000000046})

+ */ +@ComInterface(iid="{0002094B-0000-0000-C000-000000000046}") +public interface Columns { + /** + *

id(0x2)

+ */ + @ComProperty(name = "Count", dispId = 0x2) + Integer getCount(); + /** + *

id(0x0)

+ */ + @ComMethod(name = "Item", dispId = 0x0) + Column Item(Integer Index); + + /** + *

id(0x5)

+ */ + @ComMethod(name = "Add", dispId = 0x5) + Column Add(Object BeforeColumn); + + /** + *

id(0xc8)

+ */ + @ComMethod(name = "Delete", dispId = 0xc8) + void Delete(); +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ComIApplication.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ComIApplication.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ComIApplication.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ComIApplication.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,43 +1,60 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM.util.office.word; - -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.ComProperty; - -@ComInterface(iid="{00020970-0000-0000-C000-000000000046}") -public interface ComIApplication { - - @ComProperty - String getVersion(); - - @ComProperty - boolean getVisible(); - - @ComProperty - void setVisible(boolean value); - - @ComProperty - ComIDocuments getDocuments(); - - @ComProperty - ComISelection getSelection(); - - @ComProperty - ComIDocument getActiveDocument(); - - @ComMethod - void Quit(); - -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM.util.office.word; + +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.ComProperty; + +@ComInterface(iid="{00020970-0000-0000-C000-000000000046}") +public interface ComIApplication { + + @ComProperty + String getVersion(); + + @ComProperty + boolean getVisible(); + + @ComProperty + void setVisible(boolean value); + + @ComProperty + ComIDocuments getDocuments(); + + @ComProperty + ComISelection getSelection(); + + @ComProperty + ComIDocument getActiveDocument(); + + @ComMethod + void Quit(); + + /** + *

+ * id(0x172)

+ */ + @ComMethod(name = "InchesToPoints", dispId = 0x172) + Float InchesToPoints(Float Inches); +} diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ComIDocument.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ComIDocument.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ComIDocument.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ComIDocument.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,25 +1,84 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM.util.office.word; - -import com.sun.jna.platform.win32.COM.util.annotation.ComMethod; - -public interface ComIDocument { - - @ComMethod - void SaveAs(String string, WdSaveFormat wdFormatDocument); - - @ComMethod - void Close(boolean saveChanges); - -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM.util.office.word; + +import com.sun.jna.platform.win32.COM.util.annotation.ComMethod; +import com.sun.jna.platform.win32.COM.util.annotation.ComProperty; + +public interface ComIDocument { + + @ComMethod + void SaveAs(String string, WdSaveFormat wdFormatDocument); + + @ComMethod + void Close(boolean saveChanges); + + /** + *

id(0x451)

+ */ + @ComMethod(name = "Close", dispId = 0x451) + void Close(Object SaveChanges, + Object OriginalFormat, + Object RouteDocument); + + /** + *

+ * id(0x29)

+ */ + @ComProperty(name = "Content", dispId = 0x29) + Range getContent(); + + /** + *

id(0x4)

+ */ + @ComProperty(name = "Bookmarks", dispId = 0x4) + Bookmarks getBookmarks(); + + /** + *

+ * id(0x6)

+ */ + @ComProperty(name = "Tables", dispId = 0x6) + Tables getTables(); + + /** + *

id(0x228)

+ */ + @ComMethod(name = "ExportAsFixedFormat", dispId = 0x228) + void ExportAsFixedFormat(String OutputFileName, + WdExportFormat ExportFormat, + Boolean OpenAfterExport, + WdExportOptimizeFor OptimizeFor, + WdExportRange Range, + Integer From, + Integer To, + WdExportItem Item, + Boolean IncludeDocProps, + Boolean KeepIRM, + WdExportCreateBookmarks CreateBookmarks, + Boolean DocStructureTags, + Boolean BitmapMissingFonts, + Boolean UseISO19005_1, + Object FixedFormatExtClassPtr); +} diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ComIDocuments.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ComIDocuments.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ComIDocuments.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ComIDocuments.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,28 +1,39 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM.util.office.word; - -import com.sun.jna.platform.win32.COM.util.annotation.ComMethod; - -public interface ComIDocuments { - - @ComMethod - ComIDocument Open(String fileName); - - @ComMethod - ComIDocument Add(); - - @ComMethod - void Save(boolean noPrompt, WdOriginalFormat originalFormat); - -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM.util.office.word; + +import com.sun.jna.platform.win32.COM.util.annotation.ComMethod; + +public interface ComIDocuments { + + @ComMethod + ComIDocument Open(String fileName); + + @ComMethod + ComIDocument Add(); + + @ComMethod + void Save(boolean noPrompt, WdOriginalFormat originalFormat); + +} diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ComISelection.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ComISelection.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ComISelection.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ComISelection.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,24 +1,35 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM.util.office.word; - -import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; -import com.sun.jna.platform.win32.COM.util.annotation.ComMethod; - -@ComInterface -public interface ComISelection { - - @ComMethod - void TypeText(String text); - -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM.util.office.word; + +import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; +import com.sun.jna.platform.win32.COM.util.annotation.ComMethod; + +@ComInterface +public interface ComISelection { + + @ComMethod + void TypeText(String text); + +} diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ComWord_Application.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ComWord_Application.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ComWord_Application.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ComWord_Application.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,21 +1,32 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM.util.office.word; - -import com.sun.jna.platform.win32.COM.util.IUnknown; -import com.sun.jna.platform.win32.COM.util.annotation.ComObject; - -@ComObject(progId="Word.Application") -public interface ComWord_Application extends IUnknown { - -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM.util.office.word; + +import com.sun.jna.platform.win32.COM.util.IUnknown; +import com.sun.jna.platform.win32.COM.util.annotation.ComObject; + +@ComObject(progId="Word.Application") +public interface ComWord_Application extends IUnknown { + +} diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/_Font.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/_Font.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/_Font.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/_Font.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,61 @@ +/* + * 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.COM.util.office.word; + +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.ComProperty; +import com.sun.jna.platform.win32.COM.util.IDispatch; +import com.sun.jna.platform.win32.Variant.VARIANT; + +/** + *

uuid({00020952-0000-0000-C000-000000000046})

+ */ +@ComInterface(iid="{00020952-0000-0000-C000-000000000046}") +public interface _Font { + /** + *

id(0x82)

+ */ + @ComProperty(name = "Bold", dispId = 0x82) + Integer getBold(); + + /** + *

id(0x82)

+ */ + @ComProperty(name = "Bold", dispId = 0x82) + void setBold(Integer param0); + + /** + *

id(0x83)

+ */ + @ComProperty(name = "Italic", dispId = 0x83) + Integer getItalic(); + + /** + *

id(0x83)

+ */ + @ComProperty(name = "Italic", dispId = 0x83) + void setItalic(Integer param0); + +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Font.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Font.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Font.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Font.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,44 @@ +/* + * 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.COM.util.office.word; + +import com.sun.jna.platform.win32.COM.COMException; +import com.sun.jna.platform.win32.COM.util.IComEventCallbackCookie; +import com.sun.jna.platform.win32.COM.util.IComEventCallbackListener; +import com.sun.jna.platform.win32.COM.util.IConnectionPoint; +import com.sun.jna.platform.win32.COM.util.IUnknown; +import com.sun.jna.platform.win32.COM.util.annotation.ComObject; + +/** + *

uuid({000209F5-0000-0000-C000-000000000046})

+ *

interface(_Font)

+ *

interface(IUnknown)

+ */ +@ComObject(clsId = "{000209F5-0000-0000-C000-000000000046}") +public interface Font extends + _Font, + IUnknown +{ + +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/InlineShape.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/InlineShape.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/InlineShape.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/InlineShape.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,69 @@ +/* + * 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.COM.util.office.word; + +import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; +import com.sun.jna.platform.win32.COM.util.annotation.ComProperty; + +/** + *

uuid({000209A8-0000-0000-C000-000000000046})

+ */ +@ComInterface(iid="{000209A8-0000-0000-C000-000000000046}") +public interface InlineShape { + /** + *

id(0x2)

+ */ + @ComProperty(name = "Range", dispId = 0x2) + Range getRange(); + + /** + *

id(0x5)

+ */ + @ComProperty(name = "OLEFormat", dispId = 0x5) + OLEFormat getOLEFormat(); + + /** + *

id(0x8)

+ */ + @ComProperty(name = "Height", dispId = 0x8) + Float getHeight(); + + /** + *

id(0x8)

+ */ + @ComProperty(name = "Height", dispId = 0x8) + void setHeight(Float param0); + + /** + *

id(0x9)

+ */ + @ComProperty(name = "Width", dispId = 0x9) + Float getWidth(); + + /** + *

id(0x9)

+ */ + @ComProperty(name = "Width", dispId = 0x9) + void setWidth(Float param0); +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/InlineShapes.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/InlineShapes.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/InlineShapes.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/InlineShapes.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,47 @@ +/* + * 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.COM.util.office.word; + +import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; +import com.sun.jna.platform.win32.COM.util.annotation.ComMethod; + +/** + *

uuid({000209A9-0000-0000-C000-000000000046})

+ */ +@ComInterface(iid="{000209A9-0000-0000-C000-000000000046}") +public interface InlineShapes { + /** + *

id(0x18)

+ */ + @ComMethod(name = "AddOLEObject", dispId = 0x18) + InlineShape AddOLEObject(Object ClassType, + Object FileName, + Object LinkToFile, + Object DisplayAsIcon, + Object IconFileName, + Object IconIndex, + Object IconLabel, + Object Range); + +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/OLEFormat.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/OLEFormat.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/OLEFormat.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/OLEFormat.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,192 @@ +/* + * 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.COM.util.office.word; + +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.ComProperty; +import com.sun.jna.platform.win32.COM.util.IDispatch; +import com.sun.jna.platform.win32.Variant.VARIANT; + +/** + *

uuid({00020933-0000-0000-C000-000000000046})

+ */ +@ComInterface(iid="{00020933-0000-0000-C000-000000000046}") +public interface OLEFormat { + /** + *

id(0x3e8)

+ */ + @ComProperty(name = "Application", dispId = 0x3e8) + ComIApplication getApplication(); + + /** + *

id(0x3e9)

+ */ + @ComProperty(name = "Creator", dispId = 0x3e9) + Integer getCreator(); + + /** + *

id(0x3ea)

+ */ + @ComProperty(name = "Parent", dispId = 0x3ea) + com.sun.jna.platform.win32.COM.util.IDispatch getParent(); + + /** + *

id(0x2)

+ */ + @ComProperty(name = "ClassType", dispId = 0x2) + String getClassType(); + + /** + *

id(0x2)

+ */ + @ComProperty(name = "ClassType", dispId = 0x2) + void setClassType(String param0); + + /** + *

id(0x3)

+ */ + @ComProperty(name = "DisplayAsIcon", dispId = 0x3) + Boolean getDisplayAsIcon(); + + /** + *

id(0x3)

+ */ + @ComProperty(name = "DisplayAsIcon", dispId = 0x3) + void setDisplayAsIcon(Boolean param0); + + /** + *

id(0x7)

+ */ + @ComProperty(name = "IconName", dispId = 0x7) + String getIconName(); + + /** + *

id(0x7)

+ */ + @ComProperty(name = "IconName", dispId = 0x7) + void setIconName(String param0); + + /** + *

id(0x8)

+ */ + @ComProperty(name = "IconPath", dispId = 0x8) + String getIconPath(); + + /** + *

id(0x9)

+ */ + @ComProperty(name = "IconIndex", dispId = 0x9) + Integer getIconIndex(); + + /** + *

id(0x9)

+ */ + @ComProperty(name = "IconIndex", dispId = 0x9) + void setIconIndex(Integer param0); + + /** + *

id(0xa)

+ */ + @ComProperty(name = "IconLabel", dispId = 0xa) + String getIconLabel(); + + /** + *

id(0xa)

+ */ + @ComProperty(name = "IconLabel", dispId = 0xa) + void setIconLabel(String param0); + + /** + *

id(0xc)

+ */ + @ComProperty(name = "Label", dispId = 0xc) + String getLabel(); + + /** + *

id(0xe)

+ */ + @ComProperty(name = "Object", dispId = 0xe) + com.sun.jna.platform.win32.COM.util.IDispatch getObject(); + + /** + *

id(0x16)

+ */ + @ComProperty(name = "ProgID", dispId = 0x16) + String getProgID(); + + /** + *

id(0x68)

+ */ + @ComMethod(name = "Activate", dispId = 0x68) + void Activate(); + + /** + *

id(0x6a)

+ */ + @ComMethod(name = "Edit", dispId = 0x6a) + void Edit(); + + /** + *

id(0x6b)

+ */ + @ComMethod(name = "Open", dispId = 0x6b) + void Open(); + + /** + *

id(0x6d)

+ */ + @ComMethod(name = "DoVerb", dispId = 0x6d) + void DoVerb(Object VerbIndex); + + /** + *

id(0x6e)

+ */ + @ComMethod(name = "ConvertTo", dispId = 0x6e) + void ConvertTo(Object ClassType, + Object DisplayAsIcon, + Object IconFileName, + Object IconIndex, + Object IconLabel); + + /** + *

id(0x6f)

+ */ + @ComMethod(name = "ActivateAs", dispId = 0x6f) + void ActivateAs(String ClassType); + + /** + *

id(0x70)

+ */ + @ComProperty(name = "PreserveFormattingOnUpdate", dispId = 0x70) + Boolean getPreserveFormattingOnUpdate(); + + /** + *

id(0x70)

+ */ + @ComProperty(name = "PreserveFormattingOnUpdate", dispId = 0x70) + void setPreserveFormattingOnUpdate(Boolean param0); + + +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/_ParagraphFormat.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/_ParagraphFormat.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/_ParagraphFormat.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/_ParagraphFormat.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,39 @@ +/* + * 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.COM.util.office.word; + +import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; +import com.sun.jna.platform.win32.COM.util.annotation.ComProperty; + +/** + *

uuid({00020953-0000-0000-C000-000000000046})

+ */ +@ComInterface(iid="{00020953-0000-0000-C000-000000000046}") +public interface _ParagraphFormat { + /** + *

id(0x70)

+ */ + @ComProperty(name = "SpaceAfter", dispId = 0x70) + void setSpaceAfter(Float param0); +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ParagraphFormat.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ParagraphFormat.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ParagraphFormat.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ParagraphFormat.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,44 @@ +/* + * 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.COM.util.office.word; + +import com.sun.jna.platform.win32.COM.COMException; +import com.sun.jna.platform.win32.COM.util.IComEventCallbackCookie; +import com.sun.jna.platform.win32.COM.util.IComEventCallbackListener; +import com.sun.jna.platform.win32.COM.util.IConnectionPoint; +import com.sun.jna.platform.win32.COM.util.IUnknown; +import com.sun.jna.platform.win32.COM.util.annotation.ComObject; + +/** + *

uuid({000209F4-0000-0000-C000-000000000046})

+ *

interface(_ParagraphFormat)

+ *

interface(IUnknown)

+ */ +@ComObject(clsId = "{000209F4-0000-0000-C000-000000000046}") +public interface ParagraphFormat extends + _ParagraphFormat, + IUnknown +{ + +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Paragraph.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Paragraph.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Paragraph.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Paragraph.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,54 @@ +/* + * 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.COM.util.office.word; + +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.ComProperty; +import com.sun.jna.platform.win32.COM.util.IDispatch; +import com.sun.jna.platform.win32.Variant.VARIANT; + +/** + *

uuid({00020957-0000-0000-C000-000000000046})

+ */ +@ComInterface(iid="{00020957-0000-0000-C000-000000000046}") +public interface Paragraph { + /** + *

id(0x0)

+ */ + @ComProperty(name = "Range", dispId = 0x0) + Range getRange(); + + /** + *

id(0x44e)

+ */ + @ComProperty(name = "Format", dispId = 0x44e) + ParagraphFormat getFormat(); + + /** + *

id(0x44e)

+ */ + @ComProperty(name = "Format", dispId = 0x44e) + void setFormat(ParagraphFormat param0); +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Paragraphs.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Paragraphs.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Paragraphs.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Paragraphs.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,55 @@ +/* + * 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.COM.util.office.word; + +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.ComProperty; +import com.sun.jna.platform.win32.COM.util.IDispatch; +import com.sun.jna.platform.win32.Variant.VARIANT; + +/** + *

uuid({00020958-0000-0000-C000-000000000046})

+ */ +@ComInterface(iid="{00020958-0000-0000-C000-000000000046}") +public interface Paragraphs { + /** + *

id(0x2)

+ */ + @ComProperty(name = "Count", dispId = 0x2) + Integer getCount(); + + /** + *

id(0x0)

+ */ + @ComMethod(name = "Item", dispId = 0x0) + Paragraph Item(Integer Index); + + /** + *

id(0x5)

+ */ + @ComMethod(name = "Add", dispId = 0x5) + Paragraph Add(Object Range); + +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Range.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Range.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Range.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Range.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,157 @@ +/* + * 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.COM.util.office.word; + +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.ComProperty; + +/** + *

uuid({0002095E-0000-0000-C000-000000000046})

+ */ +@ComInterface(iid="{0002095E-0000-0000-C000-000000000046}") +public interface Range { + /** + *

id(0x0)

+ */ + @ComProperty(name = "Text", dispId = 0x0) + String getText(); + + /** + *

id(0x0)

+ */ + @ComProperty(name = "Text", dispId = 0x0) + void setText(String param0); + + /** + *

id(0x5)

+ */ + @ComProperty(name = "Font", dispId = 0x5) + Font getFont(); + + /** + *

id(0x5)

+ */ + @ComProperty(name = "Font", dispId = 0x5) + void setFont(Font param0); + + /** + *

id(0x3b)

+ */ + @ComProperty(name = "Paragraphs", dispId = 0x3b) + Paragraphs getParagraphs(); + + + /** + *

id(0x44e)

+ */ + @ComProperty(name = "ParagraphFormat", dispId = 0x44e) + ParagraphFormat getParagraphFormat(); + + /** + *

id(0x44e)

+ */ + @ComProperty(name = "ParagraphFormat", dispId = 0x44e) + void setParagraphFormat(ParagraphFormat param0); + + /** + *

id(0x4b)

+ */ + @ComProperty(name = "Bookmarks", dispId = 0x4b) + Bookmarks getBookmarks(); + + /** + *

id(0xd4)

+ */ + @ComMethod(name = "InsertParagraphBefore", dispId = 0xd4) + void InsertParagraphBefore(); + + + /** + *

id(0x77)

+ */ + @ComMethod(name = "Cut", dispId = 0x77) + void Cut(); + + /** + *

id(0x78)

+ */ + @ComMethod(name = "Copy", dispId = 0x78) + void Copy(); + + /** + *

id(0x79)

+ */ + @ComMethod(name = "Paste", dispId = 0x79) + void Paste(); + + /** + *

id(0x7a)

+ */ + @ComMethod(name = "InsertBreak", dispId = 0x7a) + void InsertBreak(Object Type); + + /** + *

id(0xa0)

+ */ + @ComMethod(name = "InsertParagraph", dispId = 0xa0) + void InsertParagraph(); + + /** + *

id(0xa1)

+ */ + @ComMethod(name = "InsertParagraphAfter", dispId = 0xa1) + void InsertParagraphAfter(); + + /** + *

id(0x65)

+ */ + @ComMethod(name = "Collapse", dispId = 0x65) + void Collapse(Object Direction); + + /** + *

id(0x66)

+ */ + @ComMethod(name = "InsertBefore", dispId = 0x66) + void InsertBefore(String Text); + + /** + *

id(0x68)

+ */ + @ComMethod(name = "InsertAfter", dispId = 0x68) + void InsertAfter(String Text); + + /** + *

id(0x139)

+ */ + @ComProperty(name = "Information", dispId = 0x139) + Object getInformation(WdInformation Type); + + /** + *

id(0x13f)

+ */ + @ComProperty(name = "InlineShapes", dispId = 0x13f) + InlineShapes getInlineShapes(); + +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Row.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Row.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Row.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Row.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,40 @@ +/* + * 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.COM.util.office.word; + +import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; +import com.sun.jna.platform.win32.COM.util.annotation.ComProperty; + +/** + *

uuid({00020950-0000-0000-C000-000000000046})

+ */ +@ComInterface(iid="{00020950-0000-0000-C000-000000000046}") +public interface Row { + /** + *

id(0x0)

+ */ + @ComProperty(name = "Range", dispId = 0x0) + Range getRange(); + +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Rows.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Rows.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Rows.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Rows.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,52 @@ +/* + * 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.COM.util.office.word; + +import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; +import com.sun.jna.platform.win32.COM.util.annotation.ComMethod; + +/** + *

uuid({0002094C-0000-0000-C000-000000000046})

+ */ +@ComInterface(iid="{0002094C-0000-0000-C000-000000000046}") +public interface Rows { + /** + *

id(0x0)

+ */ + @ComMethod(name = "Item", dispId = 0x0) + Row Item(Integer Index); + + /** + *

id(0x64)

+ */ + @ComMethod(name = "Add", dispId = 0x64) + Row Add(Object BeforeRow); + + /** + *

id(0xc8)

+ */ + @ComMethod(name = "Delete", dispId = 0xc8) + void Delete(); + +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Table.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Table.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Table.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Table.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,62 @@ +/* + * 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.COM.util.office.word; + +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.ComProperty; +import com.sun.jna.platform.win32.COM.util.IDispatch; +import com.sun.jna.platform.win32.Variant.VARIANT; + +/** + *

uuid({00020951-0000-0000-C000-000000000046})

+ */ +@ComInterface(iid="{00020951-0000-0000-C000-000000000046}") +public interface Table { + /** + *

id(0x0)

+ */ + @ComProperty(name = "Range", dispId = 0x0) + Range getRange(); + + /** + *

id(0x64)

+ */ + @ComProperty(name = "Columns", dispId = 0x64) + Columns getColumns(); + + /** + *

id(0x65)

+ */ + @ComProperty(name = "Rows", dispId = 0x65) + Rows getRows(); + + /** + *

id(0x11)

+ */ + @ComMethod(name = "Cell", dispId = 0x11) + Cell Cell(Integer Row, + Integer Column); + +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Tables.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Tables.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Tables.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/Tables.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,59 @@ +/* + * 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.COM.util.office.word; + +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.ComProperty; +import com.sun.jna.platform.win32.COM.util.IDispatch; +import com.sun.jna.platform.win32.Variant.VARIANT; + +/** + *

uuid({0002094D-0000-0000-C000-000000000046})

+ */ +@ComInterface(iid="{0002094D-0000-0000-C000-000000000046}") +public interface Tables { + /** + *

id(0x2)

+ */ + @ComProperty(name = "Count", dispId = 0x2) + Integer getCount(); + + /** + *

id(0x0)

+ */ + @ComMethod(name = "Item", dispId = 0x0) + Table Item(Integer Index); + + /** + *

id(0xc8)

+ */ + @ComMethod(name = "Add", dispId = 0xc8) + Table Add(Range Range, + Integer NumRows, + Integer NumColumns, + Object DefaultTableBehavior, + Object AutoFitBehavior); + +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdBreakType.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdBreakType.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdBreakType.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdBreakType.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,92 @@ +/* + * 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.COM.util.office.word; + +import com.sun.jna.platform.win32.COM.util.IComEnum; + +/** + *

uuid({58B14C6F-0FE6-3BCA-880E-E3A9C039E588})

+ */ +public enum WdBreakType implements IComEnum { + + /** + * (2) + */ + wdSectionBreakNextPage(2), + + /** + * (3) + */ + wdSectionBreakContinuous(3), + + /** + * (4) + */ + wdSectionBreakEvenPage(4), + + /** + * (5) + */ + wdSectionBreakOddPage(5), + + /** + * (6) + */ + wdLineBreak(6), + + /** + * (7) + */ + wdPageBreak(7), + + /** + * (8) + */ + wdColumnBreak(8), + + /** + * (9) + */ + wdLineBreakClearLeft(9), + + /** + * (10) + */ + wdLineBreakClearRight(10), + + /** + * (11) + */ + wdTextWrappingBreak(11), + ; + + private WdBreakType(long value) { + this.value = value; + } + private long value; + + public long getValue() { + return this.value; + } +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdCollapseDirection.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdCollapseDirection.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdCollapseDirection.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdCollapseDirection.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,52 @@ +/* + * 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.COM.util.office.word; + +import com.sun.jna.platform.win32.COM.util.IComEnum; + +/** + *

uuid({2DEF3465-D4C4-369B-B91E-68C9711F3A6C})

+ */ +public enum WdCollapseDirection implements IComEnum { + + /** + * (1) + */ + wdCollapseStart(1), + + /** + * (0) + */ + wdCollapseEnd(0), + ; + + private WdCollapseDirection(long value) { + this.value = value; + } + private long value; + + public long getValue() { + return this.value; + } +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdExportCreateBookmarks.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdExportCreateBookmarks.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdExportCreateBookmarks.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdExportCreateBookmarks.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,57 @@ +/* + * 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.COM.util.office.word; + +import com.sun.jna.platform.win32.COM.util.IComEnum; + +/** + *

uuid({42A64EC8-BC68-3DBC-8BF0-58A8CBA4AB3E})

+ */ +public enum WdExportCreateBookmarks implements IComEnum { + + /** + * (0) + */ + wdExportCreateNoBookmarks(0), + + /** + * (1) + */ + wdExportCreateHeadingBookmarks(1), + + /** + * (2) + */ + wdExportCreateWordBookmarks(2), + ; + + private WdExportCreateBookmarks(long value) { + this.value = value; + } + private long value; + + public long getValue() { + return this.value; + } +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdExportFormat.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdExportFormat.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdExportFormat.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdExportFormat.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,52 @@ +/* + * 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.COM.util.office.word; + +import com.sun.jna.platform.win32.COM.util.IComEnum; + +/** + *

uuid({5D7E6F43-3E57-353C-95E1-52E9783BE2BE})

+ */ +public enum WdExportFormat implements IComEnum { + + /** + * (17) + */ + wdExportFormatPDF(17), + + /** + * (18) + */ + wdExportFormatXPS(18), + ; + + private WdExportFormat(long value) { + this.value = value; + } + private long value; + + public long getValue() { + return this.value; + } +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdExportItem.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdExportItem.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdExportItem.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdExportItem.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,52 @@ +/* + * 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.COM.util.office.word; + +import com.sun.jna.platform.win32.COM.util.IComEnum; + +/** + *

uuid({D67854FC-9A45-33F6-A4D3-DC0002A53CE9})

+ */ +public enum WdExportItem implements IComEnum { + + /** + * (0) + */ + wdExportDocumentContent(0), + + /** + * (7) + */ + wdExportDocumentWithMarkup(7), + ; + + private WdExportItem(long value) { + this.value = value; + } + private long value; + + public long getValue() { + return this.value; + } +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdExportOptimizeFor.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdExportOptimizeFor.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdExportOptimizeFor.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdExportOptimizeFor.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,52 @@ +/* + * 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.COM.util.office.word; + +import com.sun.jna.platform.win32.COM.util.IComEnum; + +/** + *

uuid({147553BC-4DC5-3681-A445-D1C4BEA414AD})

+ */ +public enum WdExportOptimizeFor implements IComEnum { + + /** + * (0) + */ + wdExportOptimizeForPrint(0), + + /** + * (1) + */ + wdExportOptimizeForOnScreen(1), + ; + + private WdExportOptimizeFor(long value) { + this.value = value; + } + private long value; + + public long getValue() { + return this.value; + } +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdExportRange.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdExportRange.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdExportRange.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdExportRange.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,62 @@ +/* + * 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.COM.util.office.word; + +import com.sun.jna.platform.win32.COM.util.IComEnum; + +/** + *

uuid({20D65698-7CDC-3A68-A83D-D52A76FEA1A4})

+ */ +public enum WdExportRange implements IComEnum { + + /** + * (0) + */ + wdExportAllDocument(0), + + /** + * (1) + */ + wdExportSelection(1), + + /** + * (2) + */ + wdExportCurrentPage(2), + + /** + * (3) + */ + wdExportFromTo(3), + ; + + private WdExportRange(long value) { + this.value = value; + } + private long value; + + public long getValue() { + return this.value; + } +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdInformation.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdInformation.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdInformation.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdInformation.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,247 @@ +/* + * 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.COM.util.office.word; + +import com.sun.jna.platform.win32.COM.util.IComEnum; + +/** + *

uuid({26E3C1D3-6937-3EFA-8859-7FFC81869CE5})

+ */ +public enum WdInformation implements IComEnum { + + /** + * (1) + */ + wdActiveEndAdjustedPageNumber(1), + + /** + * (2) + */ + wdActiveEndSectionNumber(2), + + /** + * (3) + */ + wdActiveEndPageNumber(3), + + /** + * (4) + */ + wdNumberOfPagesInDocument(4), + + /** + * (5) + */ + wdHorizontalPositionRelativeToPage(5), + + /** + * (6) + */ + wdVerticalPositionRelativeToPage(6), + + /** + * (7) + */ + wdHorizontalPositionRelativeToTextBoundary(7), + + /** + * (8) + */ + wdVerticalPositionRelativeToTextBoundary(8), + + /** + * (9) + */ + wdFirstCharacterColumnNumber(9), + + /** + * (10) + */ + wdFirstCharacterLineNumber(10), + + /** + * (11) + */ + wdFrameIsSelected(11), + + /** + * (12) + */ + wdWithInTable(12), + + /** + * (13) + */ + wdStartOfRangeRowNumber(13), + + /** + * (14) + */ + wdEndOfRangeRowNumber(14), + + /** + * (15) + */ + wdMaximumNumberOfRows(15), + + /** + * (16) + */ + wdStartOfRangeColumnNumber(16), + + /** + * (17) + */ + wdEndOfRangeColumnNumber(17), + + /** + * (18) + */ + wdMaximumNumberOfColumns(18), + + /** + * (19) + */ + wdZoomPercentage(19), + + /** + * (20) + */ + wdSelectionMode(20), + + /** + * (21) + */ + wdCapsLock(21), + + /** + * (22) + */ + wdNumLock(22), + + /** + * (23) + */ + wdOverType(23), + + /** + * (24) + */ + wdRevisionMarking(24), + + /** + * (25) + */ + wdInFootnoteEndnotePane(25), + + /** + * (26) + */ + wdInCommentPane(26), + + /** + * (28) + */ + wdInHeaderFooter(28), + + /** + * (31) + */ + wdAtEndOfRowMarker(31), + + /** + * (32) + */ + wdReferenceOfType(32), + + /** + * (33) + */ + wdHeaderFooterType(33), + + /** + * (34) + */ + wdInMasterDocument(34), + + /** + * (35) + */ + wdInFootnote(35), + + /** + * (36) + */ + wdInEndnote(36), + + /** + * (37) + */ + wdInWordMail(37), + + /** + * (38) + */ + wdInClipboard(38), + + /** + * (41) + */ + wdInCoverPage(41), + + /** + * (42) + */ + wdInBibliography(42), + + /** + * (43) + */ + wdInCitation(43), + + /** + * (44) + */ + wdInFieldCode(44), + + /** + * (45) + */ + wdInFieldResult(45), + + /** + * (46) + */ + wdInContentControl(46), + ; + + private WdInformation(long value) { + this.value = value; + } + private long value; + + public long getValue() { + return this.value; + } +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdOriginalFormat.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdOriginalFormat.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdOriginalFormat.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdOriginalFormat.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,29 +1,40 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM.util.office.word; - -import com.sun.jna.platform.win32.COM.util.IComEnum; - -public enum WdOriginalFormat implements IComEnum { - wdOriginalDocumentFormat(1), // Original document format. - wdPromptUser(2), // Prompt user to select a document format. - wdWordDocument(0); // Microsoft Word document format. - - private WdOriginalFormat(long value) { - this.value = value; - } - private long value; - public long getValue() { - return this.value; - } -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM.util.office.word; + +import com.sun.jna.platform.win32.COM.util.IComEnum; + +public enum WdOriginalFormat implements IComEnum { + wdOriginalDocumentFormat(1), // Original document format. + wdPromptUser(2), // Prompt user to select a document format. + wdWordDocument(0); // Microsoft Word document format. + + private WdOriginalFormat(long value) { + this.value = value; + } + private long value; + public long getValue() { + return this.value; + } +} diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdSaveFormat.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdSaveFormat.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdSaveFormat.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdSaveFormat.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,54 +1,65 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM.util.office.word; - -import com.sun.jna.platform.win32.COM.util.IComEnum; - -public enum WdSaveFormat implements IComEnum { - wdFormatDocument(0), // Microsoft Office Word 97 - 2003 binary file format. - wdFormatDOSText(4), // Microsoft DOS text format. - wdFormatDOSTextLineBreaks(5), // Microsoft DOS text with line breaks preserved. - wdFormatEncodedText(7), // Encoded text format. - wdFormatFilteredHTML(10), // Filtered HTML format. - wdFormatFlatXML(19), // Open XML file format saved as a single XML file. - wdFormatFlatXMLMacroEnabled(20), // Open XML file format with macros enabled saved as a single XML file. - wdFormatFlatXMLTemplate(21), // Open XML template format saved as a XML single file. - wdFormatFlatXMLTemplateMacroEnabled(22), // Open XML template format with macros enabled saved as a single XML file. - wdFormatOpenDocumentText(23), // OpenDocument Text format. - wdFormatHTML(8), // Standard HTML format. - wdFormatRTF(6), // Rich text format (RTF). - wdFormatStrictOpenXMLDocument(24), // Strict Open XML document format. - wdFormatTemplate(1), // Word template format. - wdFormatText(2), // Microsoft Windows text format. - wdFormatTextLineBreaks(3), //Windows text format with line breaks preserved. - wdFormatUnicodeText( 7), //Unicode text format. - wdFormatWebArchive(9), //Web archive format. - wdFormatXML(11), //Extensible Markup Language (XML) format. - wdFormatDocument97( 0), // Microsoft Word 97 document format. - wdFormatDocumentDefault(16), // Word default document file format. For Word 2010, this is the DOCX format. - wdFormatPDF( 17), //PDF format. - wdFormatTemplate97( 1), // Word 97 template format. - wdFormatXMLDocument( 12), //XML document format. - wdFormatXMLDocumentMacroEnabled(13), //XML document format with macros enabled. - wdFormatXMLTemplate(14), //XML template format. - wdFormatXMLTemplateMacroEnabled(15), //XML template format with macros enabled. - wdFormatXPS(18); - - private WdSaveFormat(long value) { - this.value = value; - } - private long value; - public long getValue() { - return this.value; - } -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM.util.office.word; + +import com.sun.jna.platform.win32.COM.util.IComEnum; + +public enum WdSaveFormat implements IComEnum { + wdFormatDocument(0), // Microsoft Office Word 97 - 2003 binary file format. + wdFormatDOSText(4), // Microsoft DOS text format. + wdFormatDOSTextLineBreaks(5), // Microsoft DOS text with line breaks preserved. + wdFormatEncodedText(7), // Encoded text format. + wdFormatFilteredHTML(10), // Filtered HTML format. + wdFormatFlatXML(19), // Open XML file format saved as a single XML file. + wdFormatFlatXMLMacroEnabled(20), // Open XML file format with macros enabled saved as a single XML file. + wdFormatFlatXMLTemplate(21), // Open XML template format saved as a XML single file. + wdFormatFlatXMLTemplateMacroEnabled(22), // Open XML template format with macros enabled saved as a single XML file. + wdFormatOpenDocumentText(23), // OpenDocument Text format. + wdFormatHTML(8), // Standard HTML format. + wdFormatRTF(6), // Rich text format (RTF). + wdFormatStrictOpenXMLDocument(24), // Strict Open XML document format. + wdFormatTemplate(1), // Word template format. + wdFormatText(2), // Microsoft Windows text format. + wdFormatTextLineBreaks(3), //Windows text format with line breaks preserved. + wdFormatUnicodeText( 7), //Unicode text format. + wdFormatWebArchive(9), //Web archive format. + wdFormatXML(11), //Extensible Markup Language (XML) format. + wdFormatDocument97( 0), // Microsoft Word 97 document format. + wdFormatDocumentDefault(16), // Word default document file format. For Word 2010, this is the DOCX format. + wdFormatPDF( 17), //PDF format. + wdFormatTemplate97( 1), // Word 97 template format. + wdFormatXMLDocument( 12), //XML document format. + wdFormatXMLDocumentMacroEnabled(13), //XML document format with macros enabled. + wdFormatXMLTemplate(14), //XML template format. + wdFormatXMLTemplateMacroEnabled(15), //XML template format with macros enabled. + wdFormatXPS(18); + + private WdSaveFormat(long value) { + this.value = value; + } + private long value; + public long getValue() { + return this.value; + } +} diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdSaveOptions.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdSaveOptions.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdSaveOptions.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdSaveOptions.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,57 @@ +/* + * 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.COM.util.office.word; + +import com.sun.jna.platform.win32.COM.util.IComEnum; + +/** + *

uuid({E1B4A968-3072-3060-B6B7-1A1356D45CA2})

+ */ +public enum WdSaveOptions implements IComEnum { + + /** + * (0) + */ + wdDoNotSaveChanges(0), + + /** + * (-1) + */ + wdSaveChanges(-1), + + /** + * (-2) + */ + wdPromptToSaveChanges(-2), + ; + + private WdSaveOptions(long value) { + this.value = value; + } + private long value; + + public long getValue() { + return this.value; + } +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/Wordautomation_KB_313193_Mod.java libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/Wordautomation_KB_313193_Mod.java --- libjna-java-4.2.2/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/Wordautomation_KB_313193_Mod.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/Wordautomation_KB_313193_Mod.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,226 @@ +/* + * 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.COM.util.office; + +import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.COM.Helper; +import com.sun.jna.platform.win32.COM.util.Factory; +import com.sun.jna.platform.win32.COM.util.IDispatch; +import com.sun.jna.platform.win32.COM.util.office.office.XlChartType; +import com.sun.jna.platform.win32.COM.util.office.word.ComIApplication; +import com.sun.jna.platform.win32.COM.util.office.word.ComIDocument; +import com.sun.jna.platform.win32.COM.util.office.word.ComWord_Application; +import com.sun.jna.platform.win32.COM.util.office.word.InlineShape; +import com.sun.jna.platform.win32.COM.util.office.word.Paragraph; +import com.sun.jna.platform.win32.COM.util.office.word.Range; +import com.sun.jna.platform.win32.COM.util.office.word.Table; +import com.sun.jna.platform.win32.COM.util.office.word.WdBreakType; +import com.sun.jna.platform.win32.COM.util.office.word.WdCollapseDirection; +import com.sun.jna.platform.win32.COM.util.office.word.WdExportCreateBookmarks; +import com.sun.jna.platform.win32.COM.util.office.word.WdExportFormat; +import com.sun.jna.platform.win32.COM.util.office.word.WdExportItem; +import com.sun.jna.platform.win32.COM.util.office.word.WdExportOptimizeFor; +import com.sun.jna.platform.win32.COM.util.office.word.WdExportRange; +import com.sun.jna.platform.win32.COM.util.office.word.WdInformation; +import com.sun.jna.platform.win32.COM.util.office.word.WdSaveOptions; +import com.sun.jna.platform.win32.Ole32; +import static com.sun.jna.platform.win32.Variant.VARIANT.VARIANT_MISSING; +import java.io.File; + + +import java.io.IOException; + + +/** + * Based on VB sample: https://support.microsoft.com/de-de/kb/313193 + * + *

This version of the sample runs without a visible word instance and in the + * end shuts down word. The process creates a PDF document, that is written to a + * temporary file, which name is printed.

+ * + *

Please note: The contained type-bindings are far from complete and only + * included as sample - please use one of the generators to generate complete + * bindings or enhance the coverage yourself.

+ */ +public class Wordautomation_KB_313193_Mod { + public static void main(String[] args) throws IOException { + // Initialize COM Subsystem + Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED); + // Initialize Factory for COM object creation + Factory fact = new Factory(); + + try { + // oEndOfDoc is a predefined bookmark + final String oEndOfDoc = "\\endofdoc"; /* \endofdoc is a predefined bookmark */ + + // Start word application + ComWord_Application word = fact.createObject(ComWord_Application.class); + ComIApplication wordApp = word.queryInterface(ComIApplication.class); + + // Make word visible/invisible (invisible is default) + wordApp.setVisible(true); + + // Create an empty document (signiture of depends on bindings) + ComIDocument doc = wordApp.getDocuments().Add(); + + Helper.sleep(5); + + //Insert a paragraph at the beginning of the document. + Paragraph para1 = doc.getContent().getParagraphs().Add(VARIANT_MISSING); + para1.getRange().setText("Heading 1"); + para1.getRange().getFont().setBold(1); + //24 pt spacing after paragraph. + para1.getFormat().setSpaceAfter(24F); + para1.getRange().InsertParagraphAfter(); + + //Insert a paragraph at the end of the document. + Paragraph para2 = doc.getContent().getParagraphs().Add(doc.getBookmarks().Item(oEndOfDoc).getRange()); + para2.getRange().setText("Heading 2"); + para2.getFormat().setSpaceAfter(6F); + para2.getRange().InsertParagraphAfter(); + + //Insert another paragraph. + Paragraph para3 = doc.getContent().getParagraphs().Add(doc.getBookmarks().Item(oEndOfDoc).getRange()); + para3.getRange().setText("This is a sentence of normal text. Now here is a table:"); + para3.getRange().getFont().setBold(0); + para3.getFormat().setSpaceAfter(24F); + para3.getRange().InsertParagraphAfter(); + + //Insert a 3 x 5 table, fill it with data, and make the first row + //bold and italic. + Table table = doc.getTables().Add(doc.getBookmarks().Item(oEndOfDoc).getRange(), + 3, 5, VARIANT_MISSING, VARIANT_MISSING); + table.getRange().getParagraphFormat().setSpaceAfter(6F); + for(int r = 1; r <= 3; r++) { + for(int c = 1; c <= 5; c++) { + String strText = "r" + r + "c" + c; + table.Cell(r, c).getRange().setText(strText); + } + } + table.getRows().Item(1).getRange().getFont().setBold(1); + table.getRows().Item(1).getRange().getFont().setItalic(1); + + //Add some text after the table. + Paragraph para4 = doc.getContent().getParagraphs().Add(doc.getBookmarks().Item(oEndOfDoc).getRange()); + para4.getRange().InsertParagraphBefore(); + para4.getRange().setText("And here's another table:"); + para4.getFormat().setSpaceAfter(24F); + para4.getRange().InsertParagraphAfter(); + + //Insert a 5 x 2 table, fill it with data, and change the column widths. + table = doc.getTables().Add(doc.getBookmarks().Item(oEndOfDoc).getRange(), 5, 2, VARIANT_MISSING, VARIANT_MISSING); + table.getRange().getParagraphFormat().setSpaceAfter(6F); + + for(int r = 1; r <= 5; r++) { + for(int c = 1; c <= 2; c++) { + String strText = "r" + r + "c" + c; + table.Cell(r, c).getRange().setText(strText); + } + } + + //Change width of columns 1 & 2 + table.getColumns().Item(1).setWidth(wordApp.InchesToPoints(2F)); + table.getColumns().Item(2).setWidth(wordApp.InchesToPoints(3F)); + + //Keep inserting text. When you get to 7 inches from top of the + //document, insert a hard page break. + Range wrdRng; + float dPos = wordApp.InchesToPoints(7F); + doc.getBookmarks().Item(oEndOfDoc).getRange().InsertParagraphAfter(); + do { + wrdRng = doc.getBookmarks().Item(oEndOfDoc).getRange(); + wrdRng.getParagraphFormat().setSpaceAfter(6F); + wrdRng.InsertAfter("A line of text"); + wrdRng.InsertParagraphAfter(); + } while(dPos >= (Float) wrdRng.getInformation(WdInformation.wdVerticalPositionRelativeToPage)); + + wrdRng.Collapse(WdCollapseDirection.wdCollapseEnd); + wrdRng.InsertBreak(WdBreakType.wdPageBreak); + wrdRng.Collapse(WdCollapseDirection.wdCollapseEnd); + wrdRng.InsertAfter("We're now on page 2. Here's my chart:"); + wrdRng.InsertParagraphAfter(); + + //Insert a chart and change the chart. + InlineShape oShape = doc.getBookmarks().Item(oEndOfDoc).getRange() + .getInlineShapes().AddOLEObject( + "MSGraph.Chart.8", "", + Boolean.FALSE, Boolean.FALSE, VARIANT_MISSING, + VARIANT_MISSING, VARIANT_MISSING, VARIANT_MISSING); + + //Demonstrate use of late bound oChart and oChartApp objects to + //manipulate the chart object with MSGraph. + IDispatch oChart = oShape.getOLEFormat().getObject(); + IDispatch oChartApp = oChart.getProperty(IDispatch.class, "Application"); + + //Change the chart type to Line + oChart.setProperty("ChartType", XlChartType.xlLine.getValue()); + + //Update the chart image and quit MSGraph. + oChartApp.invokeMethod(Void.class, "Update"); + oChartApp.invokeMethod(Void.class, "Quit"); + + //... If desired, you can proceed from here using the Microsoft Graph + //Object model on the oChart and oChartApp objects to make additional + //changes to the chart. + + //Set the width of the chart. + oShape.setWidth(wordApp.InchesToPoints(6.25f)); + oShape.setHeight(wordApp.InchesToPoints(3.57f)); + + //Add text after the chart. + wrdRng = doc.getBookmarks().Item(oEndOfDoc).getRange(); + wrdRng.InsertParagraphAfter(); + wrdRng.InsertAfter("THE END."); + + File tempFile = Helper.createNotExistingFile("KB_313193_", ".pdf"); + + doc.ExportAsFixedFormat( + tempFile.getAbsolutePath(), + WdExportFormat.wdExportFormatPDF, + Boolean.FALSE, + WdExportOptimizeFor.wdExportOptimizeForOnScreen, + WdExportRange.wdExportAllDocument, + null, + null, + WdExportItem.wdExportDocumentContent, + Boolean.FALSE, + Boolean.TRUE, + WdExportCreateBookmarks.wdExportCreateNoBookmarks, + Boolean.TRUE, + Boolean.FALSE, + Boolean.TRUE, + VARIANT_MISSING); + + System.out.println("Output written to: " + tempFile.getAbsolutePath()); + + doc.Close(WdSaveOptions.wdDoNotSaveChanges, VARIANT_MISSING, VARIANT_MISSING); + + wordApp.Quit(); + } finally { + fact.disposeAll(); + Ole32.INSTANCE.CoUninitialize(); + } + } + +} diff -Nru libjna-java-4.2.2/contrib/native_window_msg/build.xml libjna-java-4.4.0/contrib/native_window_msg/build.xml --- libjna-java-4.2.2/contrib/native_window_msg/build.xml 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/native_window_msg/build.xml 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,68 @@ + + + Builds, tests, and runs the project jnacontrib.native_window_msg. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru libjna-java-4.2.2/contrib/native_window_msg/src/com/sun/jna/platform/win32/Win32WindowDemo.java libjna-java-4.4.0/contrib/native_window_msg/src/com/sun/jna/platform/win32/Win32WindowDemo.java --- libjna-java-4.2.2/contrib/native_window_msg/src/com/sun/jna/platform/win32/Win32WindowDemo.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/native_window_msg/src/com/sun/jna/platform/win32/Win32WindowDemo.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,39 +1,44 @@ /* Copyright (c) 2012 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.WString; -import com.sun.jna.platform.win32.DBT; import com.sun.jna.platform.win32.DBT.DEV_BROADCAST_DEVICEINTERFACE; import com.sun.jna.platform.win32.DBT.DEV_BROADCAST_HANDLE; import com.sun.jna.platform.win32.DBT.DEV_BROADCAST_HDR; import com.sun.jna.platform.win32.DBT.DEV_BROADCAST_OEM; import com.sun.jna.platform.win32.DBT.DEV_BROADCAST_PORT; import com.sun.jna.platform.win32.DBT.DEV_BROADCAST_VOLUME; -import com.sun.jna.platform.win32.Kernel32; -import com.sun.jna.platform.win32.User32; import com.sun.jna.platform.win32.WinDef.HMODULE; import com.sun.jna.platform.win32.WinDef.HWND; import com.sun.jna.platform.win32.WinDef.LPARAM; import com.sun.jna.platform.win32.WinDef.LRESULT; import com.sun.jna.platform.win32.WinDef.WPARAM; -import com.sun.jna.platform.win32.WinUser; import com.sun.jna.platform.win32.WinUser.HDEVNOTIFY; import com.sun.jna.platform.win32.WinUser.MSG; import com.sun.jna.platform.win32.WinUser.WNDCLASSEX; import com.sun.jna.platform.win32.WinUser.WindowProc; -import com.sun.jna.platform.win32.Wtsapi32; // TODO: Auto-generated Javadoc /** @@ -46,7 +51,7 @@ */ public Win32WindowDemo() { // define new window class - WString windowClass = new WString("MyWindowClass"); + String windowClass = new String("MyWindowClass"); HMODULE hInst = Kernel32.INSTANCE.GetModuleHandle(""); WNDCLASSEX wClass = new WNDCLASSEX(); diff -Nru libjna-java-4.2.2/contrib/ntservice/build.xml libjna-java-4.4.0/contrib/ntservice/build.xml --- libjna-java-4.2.2/contrib/ntservice/build.xml 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/ntservice/build.xml 2017-03-14 19:31:03.000000000 +0000 @@ -1,69 +1,73 @@ - - - - - - Builds, tests, and runs the project JnaContrib. - - - + + + + + + + + + + + Builds, tests, and runs the project ntservice. + + + diff -Nru libjna-java-4.2.2/contrib/ntservice/nbproject/genfiles.properties libjna-java-4.4.0/contrib/ntservice/nbproject/genfiles.properties --- libjna-java-4.2.2/contrib/ntservice/nbproject/genfiles.properties 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/ntservice/nbproject/genfiles.properties 2017-03-14 19:31:03.000000000 +0000 @@ -1,8 +1,8 @@ -build.xml.data.CRC32=94714fd7 -build.xml.script.CRC32=64128189 -build.xml.stylesheet.CRC32=240b97a2 -# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. -# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. -nbproject/build-impl.xml.data.CRC32=94714fd7 -nbproject/build-impl.xml.script.CRC32=9d2a0176 -nbproject/build-impl.xml.stylesheet.CRC32=65d7ca21 +build.xml.data.CRC32=a39dfef7 +build.xml.script.CRC32=aacb0c5e +build.xml.stylesheet.CRC32=8064a381@1.79.1.48 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=94714fd7 +nbproject/build-impl.xml.script.CRC32=9d2a0176 +nbproject/build-impl.xml.stylesheet.CRC32=65d7ca21 diff -Nru libjna-java-4.2.2/contrib/ntservice/nbproject/project.properties libjna-java-4.4.0/contrib/ntservice/nbproject/project.properties --- libjna-java-4.2.2/contrib/ntservice/nbproject/project.properties 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/ntservice/nbproject/project.properties 2017-03-14 19:31:03.000000000 +0000 @@ -1,59 +1,61 @@ -application.args= +#Tue Nov 15 21:31:35 CET 2016 +excludes= +javac.deprecation=false +build.test.results.dir=${build.dir}/test/results +run.classpath=${javac.classpath}\:${build.classes.dir} +javadoc.nonavbar=false +javac.external.vm=false +run.test.classpath=${javac.test.classpath}\:${build.test.classes.dir} +javac.processorpath=${javac.classpath} +javac.target=1.5 +annotation.processing.processors.list= +javadoc.noindex=false +javadoc.additionalparam= +includes=** build.classes.dir=${build.dir}/classes -build.classes.excludes=**/*.java,**/*.form -# This directory is removed when the project is cleaned: +javadoc.author=false +file.reference.jna-platform.jar=../platform/dist/jna-platform.jar +test.src.dir=test build.dir=build -build.generated.dir=${build.dir}/generated -# 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.test.classpath=\ - ${run.test.classpath} -# This directory is removed when the project is cleaned: -dist.dir=dist +platform.active=default_platform +javac.compilerargs= +main.class=jnacontrib.win32.TestService dist.jar=${dist.dir}/contrib-ntservice.jar -dist.javadoc.dir=${dist.dir}/javadoc +javadoc.use=true +build.sysclasspath=ignore +debug.test.classpath=${run.test.classpath} +dist.dir=dist +build.classes.excludes=**/*.java,**/*.form +javadoc.splitindex=true +javadoc.encoding= +javac.source=1.5 file.reference.jna.jar=../../build/jna.jar -libs.junit.classpath=../../lib/junit.jar +application.vendor=matthias +junit.selected.version=4 +debug.classpath=${run.classpath} +run.jvmargs= +build.generated.dir=${build.dir}/generated jar.compress=false -javac.classpath=\ - ${file.reference.jna.jar}; -# Space-separated list of extra javac options -javac.compilerargs= -javac.deprecation=false -javac.source=1.5 -javac.target=1.5 javac.test.classpath=\ ${javac.classpath}:\ ${build.classes.dir}:\ - ${libs.junit.classpath} -javadoc.additionalparam= -javadoc.author=false -javadoc.encoding= -javadoc.noindex=false -javadoc.nonavbar=false -javadoc.notree=false + ${libs.junit_4.classpath}:\ + ${libs.hamcrest.classpath} javadoc.private=false -javadoc.splitindex=true -javadoc.use=true -javadoc.version=false -javadoc.windowtitle= -main.class= -manifest.file=manifest.mf +annotation.processing.run.all.processors=true +application.title=ntservice meta.inf.dir=${src.dir}/META-INF -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.test.classpath=\ - ${javac.test.classpath}:\ - ${build.test.classes.dir} +manifest.file=manifest.mf +annotation.processing.enabled=true +dist.javadoc.dir=${dist.dir}/javadoc src.dir=src -test.src.dir=test +mkdist.disabled=false +endorsed.classpath= +javac.classpath=${file.reference.jna.jar}\:${file.reference.jna-platform.jar} +annotation.processing.enabled.in.editor=false +build.generated.sources.dir=${build.dir}/generated-sources +application.args= +javadoc.version=false +javadoc.windowtitle= +javadoc.notree=false diff -Nru libjna-java-4.2.2/contrib/ntservice/src/jnacontrib/jna/Advapi32.java libjna-java-4.4.0/contrib/ntservice/src/jnacontrib/jna/Advapi32.java --- libjna-java-4.2.2/contrib/ntservice/src/jnacontrib/jna/Advapi32.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/ntservice/src/jnacontrib/jna/Advapi32.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,196 +1,659 @@ /* - * Advapi32.java - * - * Created on 6. August 2007, 11:24 - * - * To change this template, choose Tools | Template Manager - * and open the template in the editor. + * 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 jnacontrib.jna; -import java.util.Arrays; import java.util.List; import com.sun.jna.Native; import com.sun.jna.Pointer; import com.sun.jna.Structure; -import com.sun.jna.WString; +import com.sun.jna.platform.win32.WinNT; import com.sun.jna.ptr.IntByReference; -import com.sun.jna.win32.StdCallLibrary; import com.sun.jna.win32.W32APIOptions; +import com.sun.jna.platform.win32.Winsvc.ChangeServiceConfig2Info; +import com.sun.jna.platform.win32.Winsvc.SC_HANDLE; +import com.sun.jna.platform.win32.Winsvc.SERVICE_STATUS; +import com.sun.jna.win32.W32APITypeMapper; /** - * + * * @author TB */ -public interface Advapi32 extends StdCallLibrary { - Advapi32 INSTANCE = (Advapi32) Native.loadLibrary("Advapi32", - Advapi32.class, W32APIOptions.UNICODE_OPTIONS); +public interface Advapi32 extends com.sun.jna.platform.win32.Advapi32 { - /* - * SC_HANDLE WINAPI OpenSCManager( LPCTSTR lpMachineName, LPCTSTR - * lpDatabaseName, DWORD dwDesiredAccess ); - */ - public Pointer OpenSCManager(String lpMachineName, WString lpDatabaseName, - int dwDesiredAccess); - - /* - * BOOL WINAPI CloseServiceHandle( SC_HANDLE hSCObject ); - */ - public boolean CloseServiceHandle(Pointer hSCObject); - - /* - * SC_HANDLE WINAPI OpenService( SC_HANDLE hSCManager, LPCTSTR - * lpServiceName, DWORD dwDesiredAccess ); - */ - public Pointer OpenService(Pointer hSCManager, String lpServiceName, - int dwDesiredAccess); - - /* - * BOOL WINAPI StartService( SC_HANDLE hService, DWORD dwNumServiceArgs, - * LPCTSTR* lpServiceArgVectors ); - */ - public boolean StartService(Pointer hService, int dwNumServiceArgs, - char[] lpServiceArgVectors); - - /* - * BOOL WINAPI ControlService( SC_HANDLE hService, DWORD dwControl, - * LPSERVICE_STATUS lpServiceStatus ); - */ - public boolean ControlService(Pointer hService, int dwControl, - SERVICE_STATUS lpServiceStatus); - - /* - * BOOL WINAPI StartServiceCtrlDispatcher( const SERVICE_TABLE_ENTRY* - * lpServiceTable ); - */ - public boolean StartServiceCtrlDispatcher(Structure[] lpServiceTable); + Advapi32 INSTANCE = Native.loadLibrary("Advapi32", Advapi32.class, W32APIOptions.DEFAULT_OPTIONS); - /* - * SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandler( LPCTSTR - * lpServiceName, LPHANDLER_FUNCTION lpHandlerProc ); + /** + * Connects the main thread of a service process to the service control + * manager, which causes the thread to be the service control dispatcher + * thread for the calling process. + * + * @param lpServiceTable A pointer to an array of SERVICE_TABLE_ENTRY + * structures containing one entry for each service + * that can execute in the calling process. The + * members of the last entry in the table must have + * NULL values to designate the end of the table. + * + * @return true if function succeeds. To get extended error information, call + * GetLastError. Possible error codes: + * + * + * + * + * + *
Return codeDescription
ERROR_FAILED_SERVICE_CONTROLLER_CONNECTThis error is returned if the program is being run as a console application rather than as a service. If the program will be run as a console application for debugging purposes, structure it such that service-specific code is not called when this error is returned.
ERROR_INVALID_DATAThe specified dispatch table contains entries that are not in the proper format.
ERROR_SERVICE_ALREADY_RUNNINGThe process has already called StartServiceCtrlDispatcher. Each process can call StartServiceCtrlDispatcher only one time.
+ */ + public boolean StartServiceCtrlDispatcher(SERVICE_TABLE_ENTRY[] lpServiceTable); + + /** + * Registers a function to handle service control requests. + * + *

This function has been superseded by the RegisterServiceCtrlHandlerEx + * function. A service can use either function, but the new function + * supports user-defined context data, and the new handler function supports + * additional extended control codes.

+ * + * @param lpServiceName The name of the service run by the calling thread. + * This is the service name that the service control + * program specified in the CreateService function when + * creating the service. + * + *

If the service type is SERVICE_WIN32_OWN_PROCESS, + * the function does not verify that the specified name + * is valid, because there is only one registered + * service in the process.

+ * + * @param lpHandlerProc A pointer to the handler function to be registered. + * For more information, see {@link Handler}. + * + * @return A service status handle, NULL on error. Call GetLastError to + * get extended error condition. Possible error codes: + * + * + * + * + *
Return codeDescription
ERROR_NOT_ENOUGH_MEMORYNot enough memory is available to convert an ANSI string parameter to Unicode. This error does not occur for Unicode string parameters.
ERROR_SERVICE_NOT_IN_EXEThe service entry was specified incorrectly when the process called the {@link #StartServiceCtrlDispatcher} function.
*/ - public Pointer RegisterServiceCtrlHandler(String lpServiceName, + public SERVICE_STATUS_HANDLE RegisterServiceCtrlHandler(String lpServiceName, Handler lpHandlerProc); - /* - * SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandlerEx( LPCTSTR - * lpServiceName, LPHANDLER_FUNCTION_EX lpHandlerProc, LPVOID lpContext ); + /** + * Registers a function to handle extended service control requests. + * + * @param lpServiceName The name of the service run by the calling thread. + * This is the service name that the service control + * program specified in the CreateService function when + * creating the service. + * @param lpHandlerProc The handler function to be registered. + * For more information, see HandlerEx. + * @param lpContext Any user-defined data. This parameter, which is + * passed to the handler function, can help identify + * the service when multiple services share a process. + * + * @return A service status handle on success, NULL on error. Call GetLastError + * to get extended information. Possible error codes: + * + * + * + * + *
Return codeDescription
ERROR_NOT_ENOUGH_MEMORYNot enough memory is available to convert an ANSI string parameter to Unicode. This error does not occur for Unicode string parameters.
ERROR_SERVICE_NOT_IN_EXEThe service entry was specified incorrectly when the process called the {@link #StartServiceCtrlDispatcher} function.
*/ - public Pointer RegisterServiceCtrlHandlerEx(String lpServiceName, + public SERVICE_STATUS_HANDLE RegisterServiceCtrlHandlerEx(String lpServiceName, HandlerEx lpHandlerProc, Pointer lpContext); - /* - * BOOL WINAPI SetServiceStatus( SERVICE_STATUS_HANDLE hServiceStatus, - * LPSERVICE_STATUS lpServiceStatus ); + /** + * Updates the service control manager's status information for the calling + * service. + * + * + * @param hServiceStatus A handle to the status information structure for + * the current service. This handle is returned by + * the RegisterServiceCtrlHandlerEx function. + * @param lpServiceStatus A pointer to the SERVICE_STATUS structure the + * contains the latest status information for the + * calling service. + * + * @return true if function succeeds. To get extended error information, call + * GetLastError. Possible error codes: + * + * + * + * + *
Return codeDescription
ERROR_INVALID_DATAThe specified service status structure is invalid.
ERROR_INVALID_HANDLEThe specified handle is invalid.
*/ - public boolean SetServiceStatus(Pointer hServiceStatus, + public boolean SetServiceStatus(SERVICE_STATUS_HANDLE hServiceStatus, SERVICE_STATUS lpServiceStatus); - /* - * SC_HANDLE WINAPI CreateService( SC_HANDLE hSCManager, LPCTSTR - * lpServiceName, LPCTSTR lpDisplayName, DWORD dwDesiredAccess, DWORD - * dwServiceType, DWORD dwStartType, DWORD dwErrorControl, LPCTSTR - * lpBinaryPathName, LPCTSTR lpLoadOrderGroup, LPDWORD lpdwTagId, LPCTSTR - * lpDependencies, LPCTSTR lpServiceStartName, LPCTSTR lpPassword ); + /** + * Creates a service object and adds it to the specified service control + * manager database. + * + * @param hSCManager [in] A handle to the service control manager + * database. This handle is returned by the + * OpenSCManager function and must have the + * SC_MANAGER_CREATE_SERVICE access right. For + * more information, see Service Security and + * Access Rights. + * @param lpServiceName [in] The name of the service to install. The + * maximum string length is 256 characters. The + * service control manager database preserves the + * case of the characters, but service name + * comparisons are always case insensitive. + * Forward-slash (/) and backslash (\) are not + * valid service name characters. + * @param lpDisplayName [in, optional] The display name to be used by + * user interface programs to identify the + * service. This string has a maximum length of + * 256 characters. The name is case-preserved in + * the service control manager. Display name + * comparisons are always case-insensitive. + * @param dwDesiredAccess [in] The access to the service. Before granting + * the requested access, the system checks the + * access token of the calling process. For a list + * of values, see Service Security and Access + * Rights. + * @param dwServiceType [in] The service type. This parameter can be + * one of the following values. + * + * + * + * + * + * + * + * + *
ValueMeaning
SERVICE_ADAPTER
0x00000004
Reserved.
SERVICE_FILE_SYSTEM_DRIVER
0x00000002
File system driver service.
SERVICE_KERNEL_DRIVER
0x00000001
Driver service.
SERVICE_RECOGNIZER_DRIVER
0x00000008
Reserved.
SERVICE_WIN32_OWN_PROCESS
0x00000010
Service that runs in its own process.
SERVICE_WIN32_SHARE_PROCESS
0x00000020
Service that shares a process with one or more other services. For more information, see Service Programs.
+ * + *

If you specify either SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS, and the service is running in the context of the LocalSystem account, you can also specify the following value.

+ * + * + * + * + *
ValueMeaning
SERVICE_INTERACTIVE_PROCESS
0x00000100
The service can interact with the desktop.
+ * + * @param dwStartType [in] The service start options. This parameter + * can be one of the following values. + * + * + * + * + * + * + * + * + *
ValueMeaning
SERVICE_AUTO_START
0x00000002
A service started automatically by the service control manager during system startup.
SERVICE_BOOT_START
0x00000000
A device driver started by the system loader. This value is valid only for driver services.
SERVICE_DEMAND_START
0x00000003
A service started by the service control manager when a process calls the StartService function.
SERVICE_DISABLED
0x00000004
A service that cannot be started. Attempts to start the service result in the error code ERROR_SERVICE_DISABLED.
SERVICE_SYSTEM_START
0x00000001
A device driver started by the IoInitSystem function. This value is valid only for driver services.
+ * + * @param dwErrorControl [in] The severity of the error, and action + * taken, if this service fails to start. This + * parameter can be one of the following values. + * + * + * + * + * + * + * + *
ValueMeaning
SERVICE_ERROR_CRITICAL
0x00000003
The startup program logs the error in the event log, if possible. If the last-known-good configuration is being started, the startup operation fails. Otherwise, the system is restarted with the last-known good configuration.
SERVICE_ERROR_IGNORE
0x00000000
The startup program ignores the error and continues the startup operation.
SERVICE_ERROR_NORMAL
0x00000001
The startup program logs the error in the event log but continues the startup operation.
SERVICE_ERROR_SEVERE
0x00000002
The startup program logs the error in the event log. If the last-known-good configuration is being started, the startup operation continues. Otherwise, the system is restarted with the last-known-good configuration.
+ * + * @param lpBinaryPathName [in, optional] The fully qualified path to the + * service binary file. If the path contains a + * space, it must be quoted so that it is + * correctly interpreted. For example, "d:\\my + * share\\myservice.exe" should be specified as + * "\"d:\\my share\\myservice.exe\"". + * + *

The path can also include arguments for an + * auto-start service. For example, + * "d:\\myshare\\myservice.exe arg1 arg2". These + * passed to the service entry point (typically + * the main function).

+ * + *

If you specify a path on another computer, + * the share must be accessible by the computer + * account of the local computer because this is + * the security context used in the remote call. + * However, this requirement allows any potential + * vulnerabilities in the remote computer to + * affect the local computer. Therefore, it is + * best to use a local file.

+ * + * @param lpLoadOrderGroup [in, optional] The names of the load ordering + * group of which this service is a member. + * Specify NULL or an empty string if the service + * does not belong to a group. + * + *

The startup program uses load ordering + * groups to load groups of services in a + * specified order with respect to the other + * groups. The list of load ordering groups is + * contained in the following registry value:

+ * + *

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\ServiceGroupOrder

+ * @param lpdwTagId [out, optional] A pointer to a variable that + * receives a tag value that is unique in the + * group specified in the lpLoadOrderGroup + * parameter. Specify NULL if you are not changing + * the existing tag. + * + *

You can use a tag for ordering service + * startup within a load ordering group by + * specifying a tag order vector in the following + * registry value:

+ * + *

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\GroupOrderList

+ * + *

Tags are only evaluated for driver services + * that have SERVICE_BOOT_START or + * SERVICE_SYSTEM_START start types.

+ * @param lpDependencies [in, optional] A pointer to a double + * null-terminated array of null-separated names + * of services or load ordering groups that the + * system must start before this service. Specify + * NULL or an empty string if the service has no + * dependencies. Dependency on a group means that + * this service can run if at least one member of + * the group is running after an attempt to start + * all members of the group. + * + *

You must prefix group names with + * SC_GROUP_IDENTIFIER so that they can be + * distinguished from a service name, because + * services and service groups share the same name + * space.

+ * @param lpServiceStartName [in, optional] The name of the account under + * which the service should run. If the service + * type is SERVICE_WIN32_OWN_PROCESS, use an + * account name in the form DomainName\UserName. + * The service process will be logged on as this + * user. If the account belongs to the built-in + * domain, you can specify .\UserName. + * + *

If this parameter is NULL, CreateService + * uses the LocalSystem account. If the service + * type specifies SERVICE_INTERACTIVE_PROCESS, the + * service must run in the LocalSystem account.

+ * + *

If this parameter is NT AUTHORITY\LocalService, + * CreateService uses the LocalService account. If + * the parameter is NT AUTHORITY\NetworkService, + * CreateService uses the NetworkService account.

+ * + *

A shared process can run as any user.

+ * + *

If the service type is SERVICE_KERNEL_DRIVER + * or SERVICE_FILE_SYSTEM_DRIVER, the name is the + * driver object name that the system uses to load + * the device driver. Specify NULL if the driver + * is to use a default object name created by the + * I/O system.

+ * + *

A service can be configured to use a managed + * account or a virtual account. If the service is + * configured to use a managed service account, + * the name is the managed service account name. + * If the service is configured to use a virtual + * account, specify the name as NT + * SERVICE\ServiceName. For more information about + * managed service accounts and virtual accounts, + * see the Service Accounts Step-by-Step Guide. + * + *

Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: + * Managed service accounts and virtual accounts are not supported until + * Windows 7 and Windows Server 2008 R2.

+ * @param lpPassword [in, optional] The password to the account name + * specified by the lpServiceStartName parameter. + * Specify an empty string if the account has no + * password or if the service runs in the + * LocalService, NetworkService, or LocalSystem + * account. For more information, see Service + * Record List. + * + *

If the account name specified by the + * lpServiceStartName parameter is the name of a + * managed service account or virtual account + * name, the lpPassword parameter must be NULL.

+ * + *

Passwords are ignored for driver services.

+ * + * @return SC_HANDLE on success, NULL on error. Call GetLastError to + * get extended error condition. Possible error codes: + * + * + * + * + * + * + * + * + * + * + * + * + *
Return codeDescription
ERROR_ACCESS_DENIEDThe handle to the SCM database does not have the SC_MANAGER_CREATE_SERVICE access right.
ERROR_CIRCULAR_DEPENDENCYA circular service dependency was specified.
ERROR_DUPLICATE_SERVICE_NAMEThe display name already exists in the service control manager database either as a service name or as another display name.
ERROR_INVALID_HANDLEThe handle to the specified service control manager database is invalid.
ERROR_INVALID_NAMEThe specified service name is invalid.
ERROR_INVALID_PARAMETERA parameter that was specified is invalid.
ERROR_INVALID_SERVICE_ACCOUNTThe user account name specified in the lpServiceStartName parameter does not exist.
ERROR_SERVICE_EXISTSThe specified service already exists in this database.
ERROR_SERVICE_MARKED_FOR_DELETEThe specified service already exists in this database and has been marked for deletion.
*/ - public Pointer CreateService(Pointer hSCManager, String lpServiceName, + public SC_HANDLE CreateService(SC_HANDLE hSCManager, String lpServiceName, String lpDisplayName, int dwDesiredAccess, int dwServiceType, int dwStartType, int dwErrorControl, String lpBinaryPathName, String lpLoadOrderGroup, IntByReference lpdwTagId, String lpDependencies, String lpServiceStartName, String lpPassword); - /* - * BOOL WINAPI DeleteService( SC_HANDLE hService ); + /** + * Marks the specified service for deletion from the service control manager database. + * + * @param hService [in] A handle to the service. This handle is returned by + * the OpenService or CreateService function, and it must + * have the DELETE access right. + * + * @return true if function succeeds. To get extended error information, call + * GetLastError. Possible error codes: + * + * + * + * + * + * + *
Return codeDescription
ERROR_ACCESS_DENIEDThe handle does not have the DELETE access right.
ERROR_INVALID_HANDLEThe specified handle is invalid.
ERROR_SERVICE_MARKED_FOR_DELETEThe specified service has already been marked for deletion.
*/ - public boolean DeleteService(Pointer hService); - - /* - * BOOL WINAPI ChangeServiceConfig2( SC_HANDLE hService, DWORD dwInfoLevel, - * LPVOID lpInfo ); - */ - public boolean ChangeServiceConfig2(Pointer hService, int dwInfoLevel, - ChangeServiceConfig2Info lpInfo); - - /* - * LONG WINAPI RegEnumValue( HKEY hKey, DWORD dwIndex, LPTSTR lpValueName, - * LPDWORD lpcchValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE - * lpData, LPDWORD lpcbData ); - */ - public int RegEnumValue(int hKey, int dwIndex, char[] lpValueName, - IntByReference lpcchValueName, IntByReference reserved, - IntByReference lpType, byte[] lpData, IntByReference lpcbData); + public boolean DeleteService(SC_HANDLE hService); + /** + * The entry point for a service. + */ interface SERVICE_MAIN_FUNCTION extends StdCallCallback { - /* - * VOID WINAPI ServiceMain( DWORD dwArgc, LPTSTR* lpszArgv ); + + /** + * + * @param dwArgc [in] The number of arguments in the lpszArgv array. + * @param lpszArgv [in] The null-terminated argument strings passed to + * the service by the call to the StartService function + * that started the service. If there are no arguments, + * this parameter can be NULL. Otherwise, the first + * argument (lpszArgv[0]) is the name of the service, + * followed by any additional arguments (lpszArgv[1] + * through lpszArgv[dwArgc-1]). + * + *

If the user starts a manual service using the + * Services snap-in from the Control Panel, the strings + * for the lpszArgv parameter come from the properties + * dialog box for the service (from the Services snap-in, + * right-click the service entry, click Properties, and + * enter the parameters in Start parameters.) */ public void callback(int dwArgc, Pointer lpszArgv); } + /** + * An application-defined callback function used with the + * RegisterServiceCtrlHandler function. A service program can use it as the + * control handler function of a particular service. + * + *

+ * This function has been superseded by the {@link HandlerEx} control handler + * function used with the {@link #RegisterServiceCtrlHandlerEx} function. A service + * can use either control handler, but the new control handler supports + * user-defined context data and additional extended control codes.

+ */ interface Handler extends StdCallCallback { - /* - * VOID WINAPI Handler( DWORD fdwControl ); + + /** + * @param fdwControl [in] The control code. This parameter can be one of + * the following values. + * + * + * + * + * + * + * + * + * + * + * + * + *
Control codeMeaning
SERVICE_CONTROL_CONTINUE
0x00000003
Notifies a paused service that it should resume.
SERVICE_CONTROL_INTERROGATE
0x00000004
Notifies a service that it should report its current status information to the service control manager.
The handler should simply return NO_ERROR; the SCM is aware of the current state of the service.
SERVICE_CONTROL_NETBINDADD
0x00000007
Notifies a network service that there is a new component for binding. The service should bind to the new component.
Applications should use Plug and Play functionality instead.
SERVICE_CONTROL_NETBINDDISABLE
0x0000000A
Notifies a network service that one of its bindings has been disabled. The service should reread its binding information and remove the binding.
Applications should use Plug and Play functionality instead.
SERVICE_CONTROL_NETBINDENABLE
0x00000009
Notifies a network service that a disabled binding has been enabled. The service should reread its binding information and add the new binding.
Applications should use Plug and Play functionality instead.
SERVICE_CONTROL_NETBINDREMOVE
0x00000008
Notifies a network service that a component for binding has been removed. The service should reread its binding information and unbind from the removed component.
Applications should use Plug and Play functionality instead.
SERVICE_CONTROL_PARAMCHANGE
0x00000006
Notifies a service that its startup parameters have changed. The service should reread its startup parameters.
SERVICE_CONTROL_PAUSE
0x00000002
Notifies a service that it should pause.
SERVICE_CONTROL_SHUTDOWN
0x00000005
Notifies a service that the system is shutting down so the service can perform cleanup tasks.
If a service accepts this control code, it must stop after it performs its cleanup tasks and return NO_ERROR. After the SCM sends this control code, it will not send other control codes to the service.
SERVICE_CONTROL_STOP
0x00000001
Notifies a service that it should stop.
If a service accepts this control code, it must stop upon receipt and return NO_ERROR. After the SCM sends this control code, it does not send other control codes.
Windows XP: If the service returns NO_ERROR and continues to run, it continues to receive control codes. This behavior changed starting with Windows Server 2003 and Windows XP with SP2.
+ * + *

This parameter can also be a user-defined control code, as described in the following table.

+ * + * + * + * + *
Control codeMeaning
Range 128 to 255.The service defines the action associated with the control code.
*/ public void callback(int fdwControl); } + /** + * An application-defined callback function used with the + * RegisterServiceCtrlHandlerEx function. A service program can use it as + * the control handler function of a particular service. + * + *

This function supersedes the Handler control handler function used + * with the {@link RegisterServiceCtrlHandler} function. A service can use either + * control handler, but the new control handler supports user-defined + * context data and additional extended control codes.

+ */ interface HandlerEx extends StdCallCallback { - /* - * DWORD WINAPI HandlerEx( DWORD dwControl, DWORD dwEventType, LPVOID - * lpEventData, LPVOID lpContext ); + + /** + * @param dwControl [in] The control code. This parameter can be one of + * the following values. + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Control codeMeaning
SERVICE_CONTROL_CONTINUE
0x00000003
Notifies a paused service that it should resume.
SERVICE_CONTROL_INTERROGATE
0x00000004
Notifies a service that it should report its current status information to the service control manager.
The handler should simply return NO_ERROR; the SCM is aware of the current state of the service.
SERVICE_CONTROL_NETBINDADD
0x00000007
Notifies a network service that there is a new component for binding. The service should bind to the new component.
Applications should use Plug and Play functionality instead.
SERVICE_CONTROL_NETBINDDISABLE
0x0000000A
Notifies a network service that one of its bindings has been disabled. The service should reread its binding information and remove the binding.
Applications should use Plug and Play functionality instead.
SERVICE_CONTROL_NETBINDENABLE
0x00000009
Notifies a network service that a disabled binding has been enabled. The service should reread its binding information and add the new binding.
Applications should use Plug and Play functionality instead.
SERVICE_CONTROL_NETBINDREMOVE
0x00000008
Notifies a network service that a component for binding has been removed. The service should reread its binding information and unbind from the removed component.
Applications should use Plug and Play functionality instead.
SERVICE_CONTROL_PARAMCHANGE
0x00000006
Notifies a service that its startup parameters have changed. The service should reread its startup parameters.
SERVICE_CONTROL_PAUSE
0x00000002
Notifies a service that it should pause.
SERVICE_CONTROL_PRESHUTDOWN
0x0000000F
Notifies a service that the system will be shutting down. Services that need additional time to perform cleanup tasks beyond the tight time restriction at system shutdown can use this notification. The service control manager sends this notification to applications that have registered for it before sending a SERVICE_CONTROL_SHUTDOWN notification to applications that have registered for that notification.
A service that handles this notification blocks system shutdown until the service stops or the preshutdown time-out interval specified through SERVICE_PRESHUTDOWN_INFO expires. Because this affects the user experience, services should use this feature only if it is absolutely necessary to avoid data loss or significant recovery time at the next system start.
Windows Server 2003 and Windows XP: This value is not supported.
SERVICE_CONTROL_SHUTDOWN
0x00000005
Notifies a service that the system is shutting down so the service can perform cleanup tasks.
If a service accepts this control code, it must stop after it performs its cleanup tasks and return NO_ERROR. After the SCM sends this control code, it will not send other control codes to the service.
SERVICE_CONTROL_STOP
0x00000001
Notifies a service that it should stop.
If a service accepts this control code, it must stop upon receipt and return NO_ERROR. After the SCM sends this control code, it does not send other control codes.
Windows XP: If the service returns NO_ERROR and continues to run, it continues to receive control codes. This behavior changed starting with Windows Server 2003 and Windows XP with SP2.
+ * + *

This parameter can also be one of the following extended control codes. Note that these control codes are not supported by the {@link Handler} function.

+ * + * + * + * + * + * + * + * + * + * + *
Control codeMeaning
SERVICE_CONTROL_DEVICEEVENT
0x0000000B
Notifies a service of device events. (The service must have registered to receive these notifications using the RegisterDeviceNotification function.) The dwEventType and lpEventData parameters contain additional information.
SERVICE_CONTROL_HARDWAREPROFILECHANGE
0x0000000C
Notifies a service that the computer's hardware profile has changed. The dwEventType parameter contains additional information.
SERVICE_CONTROL_POWEREVENT
0x0000000D
Notifies a service of system power events. The dwEventType parameter contains additional information. If dwEventType is PBT_POWERSETTINGCHANGE, the lpEventData parameter also contains additional information.
SERVICE_CONTROL_SESSIONCHANGE
0x0000000E
Notifies a service of session change events. Note that a service will only be notified of a user logon if it is fully loaded before the logon attempt is made. The dwEventType and lpEventData parameters contain additional information.
SERVICE_CONTROL_TIMECHANGE
0x00000010
Notifies a service that the system time has changed. The lpEventData parameter contains additional information. The dwEventType parameter is not used.
Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This control code is not supported.
SERVICE_CONTROL_TRIGGEREVENT
0x00000020
Notifies a service registered for a service trigger event that the event has occurred.
Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This control code is not supported.
SERVICE_CONTROL_USERMODEREBOOT
0x00000040
Notifies a service that the user has initiated a reboot.
Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This control code is not supported.
+ * + *

This parameter can also be a user-defined control code, as described in the following table.

+ * + * + * + * + *
Control codeMeaning
Range 128 to 255.The service defines the action associated with the control code.
+ * + * @param dwEventType The type of event that has occurred. This + * parameter is used if dwControl is + * SERVICE_CONTROL_DEVICEEVENT, + * SERVICE_CONTROL_HARDWAREPROFILECHANGE, + * SERVICE_CONTROL_POWEREVENT, or + * SERVICE_CONTROL_SESSIONCHANGE. Otherwise, it is + * zero. + * + *

If dwControl is SERVICE_CONTROL_DEVICEEVENT, this parameter can be + * one of the following values:

+ * + *
    + *
  • DBT_DEVICEARRIVAL
  • + *
  • DBT_DEVICEREMOVECOMPLETE
  • + *
  • DBT_DEVICEQUERYREMOVE
  • + *
  • DBT_DEVICEQUERYREMOVEFAILED
  • + *
  • DBT_DEVICEREMOVEPENDING DBT_CUSTOMEVENT
  • + *
+ * + *

If dwControl is SERVICE_CONTROL_HARDWAREPROFILECHANGE, this parameter + * can be one of the following values:

+ * + *
    + *
  • DBT_CONFIGCHANGED
  • + *
  • DBT_QUERYCHANGECONFIG
  • + *
  • DBT_CONFIGCHANGECANCELED
  • + *
+ * + *

If dwControl is SERVICE_CONTROL_POWEREVENT, this parameter can be one + * of the values specified in the wParam parameter of the + * WM_POWERBROADCAST message.

+ * + *

If dwControl is SERVICE_CONTROL_SESSIONCHANGE, this parameter can be + * one of the values specified in the wParam parameter of the + * WM_WTSSESSION_CHANGE message.

+ * + * @param lpEventData [in] Additional device information, if required. + * The format of this data depends on the value of + * the dwControl and dwEventType parameters. + * + *

If dwControl is SERVICE_CONTROL_DEVICEEVENT, this data corresponds to + * the lParam parameter that applications receive as part of a + * WM_DEVICECHANGE message.

+ * + *

If dwControl is SERVICE_CONTROL_POWEREVENT and dwEventType is + * PBT_POWERSETTINGCHANGE, this data is a pointer to a + * POWERBROADCAST_SETTING structure.

+ * + *

If dwControl is SERVICE_CONTROL_SESSIONCHANGE, this parameter is a + * pointer to a WTSSESSION_NOTIFICATION structure.

+ * + *

If dwControl is SERVICE_CONTROL_TIMECHANGE, this data is a pointer to + * a SERVICE_TIMECHANGE_INFO structure.

+ * + * @param lpContext [in] User-defined data passed from + * {@link RegisterServiceCtrlHandlerEx}. When multiple + * services share a process, the lpContext parameter + * can help identify the service. + * + * @return The return value for this function depends on the control + * code received. + * + *

The following list identifies the rules for this return value:

+ * + *
    + *
  • In general, if your service does not handle the control, return + * ERROR_CALL_NOT_IMPLEMENTED. However, your service should return + * NO_ERROR for SERVICE_CONTROL_INTERROGATE even if your service does + * not handle it.
  • + *
  • If your service handles SERVICE_CONTROL_STOP or + * SERVICE_CONTROL_SHUTDOWN, return NO_ERROR.
  • + *
  • If your service handles SERVICE_CONTROL_DEVICEEVENT, return + * NO_ERROR to grant the request and an error code to deny the + * request.
  • + *
  • If your service handles SERVICE_CONTROL_HARDWAREPROFILECHANGE, + * return NO_ERROR to grant the request and an error code to deny the + * request.<
  • If your service handles + * SERVICE_CONTROL_POWEREVENT, return NO_ERROR to grant the request and + * an error code to deny the request.
  • + *
  • For all other control codes your service handles, return + * NO_ERROR.
  • + *
*/ public int callback(int dwControl, int dwEventType, Pointer lpEventData, Pointer lpContext); } - /* - * typedef struct _SERVICE_STATUS { DWORD dwServiceType; DWORD - * dwCurrentState; DWORD dwControlsAccepted; DWORD dwWin32ExitCode; DWORD - * dwServiceSpecificExitCode; DWORD dwCheckPoint; DWORD dwWaitHint; } - * SERVICE_STATUS,LPSERVICE_STATUS; - */ - public static class SERVICE_STATUS extends Structure { - public int dwServiceType; - public int dwCurrentState; - public int dwControlsAccepted; - public int dwWin32ExitCode; - public int dwServiceSpecificExitCode; - public int dwCheckPoint; - public int dwWaitHint; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "dwServiceType", "dwCurrentState", "dwControlsAccepted", "dwWin32ExitCode", "dwServiceSpecificExitCode", "dwCheckPoint", "dwWaitHint" }); - } - } - - /* - * typedef struct _SERVICE_TABLE_ENTRY { LPTSTR lpServiceName; - * LPSERVICE_MAIN_FUNCTION lpServiceProc; } SERVICE_TABLE_ENTRY, - * LPSERVICE_TABLE_ENTRY; + /** + * Specifies the ServiceMain function for a service that can run in the + * calling process. It is used by the StartServiceCtrlDispatcher function. */ public static class SERVICE_TABLE_ENTRY extends Structure { + + public static final List FIELDS = createFieldsOrder("lpServiceName", "lpServiceProc"); + /** + * The name of a service to be run in this service process. + * + *

+ * If the service is installed with the SERVICE_WIN32_OWN_PROCESS + * service type, this member is ignored, but cannot be NULL. This member + * can be an empty string ("").

+ *

+ * If the service is installed with the SERVICE_WIN32_SHARE_PROCESS + * service type, this member specifies the name of the service that uses + * the ServiceMain function pointed to by the lpServiceProc member.

+ */ public String lpServiceName; public SERVICE_MAIN_FUNCTION lpServiceProc; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "lpServiceName", "lpServiceProc" }); + + public SERVICE_TABLE_ENTRY() { + super(W32APITypeMapper.DEFAULT); } - } - public static abstract class ChangeServiceConfig2Info extends Structure { + @Override + protected List getFieldOrder() { + return FIELDS; + } } - /* - * typedef struct _SERVICE_DESCRIPTION { LPTSTR lpDescription; } - * SERVICE_DESCRIPTION,LPSERVICE_DESCRIPTION; + /** + * + * Contains a service description. + * + *

+ * The description of the service. If this member is NULL, the description + * remains unchanged. If this value is an empty string (""), the current + * description is deleted.

+ *

+ * The service description must not exceed the size of a registry value of + * type REG_SZ.

+ *

+ * This member can specify a localized string using the following + * format:

+ *

+ * @[path\]dllname,-strID

+ *

+ * The string with identifier strID is loaded from dllname; the path is + * optional. For more information, see RegLoadMUIString.

+ *

+ * Windows Server 2003 and Windows XP: Localized strings + * are not supported until Windows Vista.

+ * */ public static class SERVICE_DESCRIPTION extends ChangeServiceConfig2Info { + + public static final List FIELDS = createFieldsOrder("lpDescription"); public String lpDescription; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "lpDescription" }); + + @Override + protected List getFieldOrder() { + return FIELDS; + } + } + + public static class SERVICE_STATUS_HANDLE extends WinNT.HANDLE { + + public SERVICE_STATUS_HANDLE() { + } + + public SERVICE_STATUS_HANDLE(Pointer p) { + super(p); } } } diff -Nru libjna-java-4.2.2/contrib/ntservice/src/jnacontrib/jna/WINERROR.java libjna-java-4.4.0/contrib/ntservice/src/jnacontrib/jna/WINERROR.java --- libjna-java-4.2.2/contrib/ntservice/src/jnacontrib/jna/WINERROR.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/ntservice/src/jnacontrib/jna/WINERROR.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -/* - * WINERROR.java - * - * Created on 7. August 2007, 08:09 - * - * To change this template, choose Tools | Template Manager - * and open the template in the editor. - */ - -package jnacontrib.jna; - - -/** - * - * @author TB - */ -public interface WINERROR { - public final static int ERROR_SUCCESS = 0; - public final static int NO_ERROR = 0; - public final static int ERROR_FILE_NOT_FOUND = 2; - public final static int ERROR_MORE_DATA = 234; -} diff -Nru libjna-java-4.2.2/contrib/ntservice/src/jnacontrib/jna/WINNT.java libjna-java-4.4.0/contrib/ntservice/src/jnacontrib/jna/WINNT.java --- libjna-java-4.2.2/contrib/ntservice/src/jnacontrib/jna/WINNT.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/ntservice/src/jnacontrib/jna/WINNT.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -/* - * WINNT.java - * - * Created on 8. August 2007, 13:41 - * - * To change this template, choose Tools | Template Manager - * and open the template in the editor. - */ - -package jnacontrib.jna; - -/** - * - * @author TB - */ -public interface WINNT { - public final static int DELETE = 0x00010000; - public final static int READ_CONTROL = 0x00020000; - public final static int WRITE_DAC = 0x00040000; - public final static int WRITE_OWNER = 0x00080000; - public final static int SYNCHRONIZE = 0x00100000; - - public final static int STANDARD_RIGHTS_REQUIRED = 0x000F0000; - - public final static int STANDARD_RIGHTS_READ = READ_CONTROL; - public final static int STANDARD_RIGHTS_WRITE = READ_CONTROL; - public final static int STANDARD_RIGHTS_EXECUTE = READ_CONTROL; - - public final static int STANDARD_RIGHTS_ALL = 0x001F0000; - - public final static int SPECIFIC_RIGHTS_ALL = 0x0000FFFF; - - public final static int GENERIC_EXECUTE = 0x20000000; - - public final static int SERVICE_WIN32_OWN_PROCESS = 0x00000010; -} diff -Nru libjna-java-4.2.2/contrib/ntservice/src/jnacontrib/jna/WINSVC.java libjna-java-4.4.0/contrib/ntservice/src/jnacontrib/jna/WINSVC.java --- libjna-java-4.2.2/contrib/ntservice/src/jnacontrib/jna/WINSVC.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/ntservice/src/jnacontrib/jna/WINSVC.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,104 +0,0 @@ -/* - * WINSVC.java - * - * Created on 8. August 2007, 15:07 - * - * To change this template, choose Tools | Template Manager - * and open the template in the editor. - */ - -package jnacontrib.jna; - - -/** - * - * @author TB - */ -public interface WINSVC { - public final static int SERVICE_CONTROL_STOP = 0x00000001; - public final static int SERVICE_CONTROL_SHUTDOWN = 0x00000005; - - public final static int SERVICE_STOPPED = 0x00000001; - public final static int SERVICE_START_PENDING = 0x00000002; - public final static int SERVICE_STOP_PENDING = 0x00000003; - public final static int SERVICE_RUNNING = 0x00000004; - public final static int SERVICE_CONTINUE_PENDING = 0x00000005; - public final static int SERVICE_PAUSE_PENDING = 0x00000006; - public final static int SERVICE_PAUSED = 0x00000007; - - public final static int SERVICE_ACCEPT_STOP = 0x00000001; - public final static int SERVICE_ACCEPT_PAUSE_CONTINUE = 0x00000002; - public final static int SERVICE_ACCEPT_SHUTDOWN = 0x00000004; - public final static int SERVICE_ACCEPT_PARAMCHANGE = 0x00000008; - public final static int SERVICE_ACCEPT_NETBINDCHANGE = 0x00000010; - - public final static int SC_MANAGER_CONNECT = 0x0001; - public final static int SC_MANAGER_CREATE_SERVICE = 0x0002; - public final static int SC_MANAGER_ENUMERATE_SERVICE = 0x0004; - public final static int SC_MANAGER_LOCK = 0x0008; - public final static int SC_MANAGER_QUERY_LOCK_STATUS = 0x0010; - public final static int SC_MANAGER_MODIFY_BOOT_CONFIG = 0x0020; - - public final static int SC_MANAGER_ALL_ACCESS = WINNT.STANDARD_RIGHTS_REQUIRED | - SC_MANAGER_CONNECT | - SC_MANAGER_CREATE_SERVICE | - SC_MANAGER_ENUMERATE_SERVICE | - SC_MANAGER_LOCK | - SC_MANAGER_QUERY_LOCK_STATUS | - SC_MANAGER_MODIFY_BOOT_CONFIG; - - public final static int SERVICE_QUERY_CONFIG = 0x0001; - public final static int SERVICE_CHANGE_CONFIG = 0x0002; - public final static int SERVICE_QUERY_STATUS = 0x0004; - public final static int SERVICE_ENUMERATE_DEPENDENTS = 0x0008; - public final static int SERVICE_START = 0x0010; - public final static int SERVICE_STOP = 0x0020; - public final static int SERVICE_PAUSE_CONTINUE = 0x0040; - public final static int SERVICE_INTERROGATE = 0x0080; - public final static int SERVICE_USER_DEFINED_CONTROL = 0x0100; - - public final static int SERVICE_ALL_ACCESS = WINNT.STANDARD_RIGHTS_REQUIRED | - SERVICE_QUERY_CONFIG | - SERVICE_CHANGE_CONFIG | - SERVICE_QUERY_STATUS | - SERVICE_ENUMERATE_DEPENDENTS | - SERVICE_START | - SERVICE_STOP | - SERVICE_PAUSE_CONTINUE | - SERVICE_INTERROGATE | - SERVICE_USER_DEFINED_CONTROL; - - public final static int SERVICE_CONFIG_DESCRIPTION = 1; - public final static int SERVICE_CONFIG_FAILURE_ACTIONS = 2; - - public final static int SERVICE_KERNEL_DRIVER = 0x00000001; - public final static int SERVICE_FILE_SYSTEM_DRIVER = 0x00000002; - public final static int SERVICE_ADAPTER = 0x00000004; - public final static int SERVICE_RECOGNIZER_DRIVER = 0x00000008; - - public final static int SERVICE_DRIVER = SERVICE_KERNEL_DRIVER | - SERVICE_FILE_SYSTEM_DRIVER | - SERVICE_RECOGNIZER_DRIVER; - - public final static int SERVICE_WIN32_OWN_PROCESS = 0x00000010; - public final static int SERVICE_WIN32_SHARE_PROCESS = 0x00000020; - public final static int SERVICE_WIN32 = SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS; - - public final static int SERVICE_INTERACTIVE_PROCESS = 0x00000100; - - public final static int SERVICE_TYPE_ALL = SERVICE_WIN32 | - SERVICE_ADAPTER | - SERVICE_DRIVER | - SERVICE_INTERACTIVE_PROCESS; - - public final static int SERVICE_BOOT_START = 0x00000000; - public final static int SERVICE_SYSTEM_START = 0x00000001; - public final static int SERVICE_AUTO_START = 0x00000002; - public final static int SERVICE_DEMAND_START = 0x00000003; - public final static int SERVICE_DISABLED = 0x00000004; - - public final static int SERVICE_ERROR_IGNORE = 0x00000000; - public final static int SERVICE_ERROR_NORMAL = 0x00000001; - public final static int SERVICE_ERROR_SEVERE = 0x00000002; - public final static int SERVICE_ERROR_CRITICAL = 0x00000003; -} diff -Nru libjna-java-4.2.2/contrib/ntservice/src/jnacontrib/win32/TestService.java libjna-java-4.4.0/contrib/ntservice/src/jnacontrib/win32/TestService.java --- libjna-java-4.2.2/contrib/ntservice/src/jnacontrib/win32/TestService.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/ntservice/src/jnacontrib/win32/TestService.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,10 +1,24 @@ /* - * TestService.java - * - * Created on 12. September 2007, 12:49 - * - * To change this template, choose Tools | Template Manager - * and open the template in the editor. + * 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 jnacontrib.win32; diff -Nru libjna-java-4.2.2/contrib/ntservice/src/jnacontrib/win32/Win32Service.java libjna-java-4.4.0/contrib/ntservice/src/jnacontrib/win32/Win32Service.java --- libjna-java-4.2.2/contrib/ntservice/src/jnacontrib/win32/Win32Service.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/ntservice/src/jnacontrib/win32/Win32Service.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,16 +1,41 @@ /* - * Win32Service.java - * - * Created on 12. September 2007, 12:05 - * - * To change this template, choose Tools | Template Manager - * and open the template in the editor. + * 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 jnacontrib.win32; import jnacontrib.jna.*; import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.WinError; +import com.sun.jna.platform.win32.WinNT; +import com.sun.jna.platform.win32.Winsvc; +import com.sun.jna.platform.win32.Winsvc.SC_HANDLE; +import com.sun.jna.platform.win32.Winsvc.SERVICE_STATUS; +import java.io.File; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLClassLoader; +import jnacontrib.jna.Advapi32.SERVICE_STATUS_HANDLE; +import jnacontrib.jna.Advapi32.SERVICE_TABLE_ENTRY; /** * Baseclass for a Win32 service. @@ -19,7 +44,7 @@ protected String serviceName; private ServiceMain serviceMain; private ServiceControl serviceControl; - private Pointer serviceStatusHandle; + private SERVICE_STATUS_HANDLE serviceStatusHandle; private Object waitObject = new Object(); /** @@ -39,12 +64,34 @@ * @param dependencies array of other services to depend on or null * @param account service account or null for LocalSystem * @param password password for service account or null - * @throws java.lang.Exception * @return true on success */ public boolean install(String displayName, String description, String[] dependencies, String account, String password) { - return(install(displayName, description, dependencies, account, password, "java.exe -cp \"" + - System.getProperty("java.class.path") + "\" -Xrs " + this.getClass().getName())); + // This needs to be adjusted for a production implementation! + // + // Determine the JVM used to invoke this installer and use it as + // runtime for the service + String javaHome = System.getProperty("java.home"); + String javaBinary = javaHome + "\\bin\\java.exe"; + // Assumption: This is started as: + // + // java -jar + // + // This is not portable, as it assumes, that this establishes a CL hierachy, + // that starts with one ClassLoader that loads the main jar (this service + // implementation) and its childs are resposible for loading referenced + // jars. + URLClassLoader cl = (URLClassLoader) Win32Service.class.getClassLoader(); + URL jarPath = cl.getURLs()[0]; + + try { + File jar = new File(jarPath.toURI()); + return(install(displayName, description, dependencies, account, password, + javaBinary + " -jar \"" + jar.getAbsolutePath() + "\"" + )); + } catch (URISyntaxException ex) { + return false; + } } /** @@ -62,7 +109,7 @@ public boolean install(String displayName, String description, String[] dependencies, String account, String password, String command) { Advapi32 advapi32; Advapi32.SERVICE_DESCRIPTION desc; - Pointer serviceManager, service; + SC_HANDLE service, serviceManager; boolean success = false; String dep = ""; @@ -77,17 +124,17 @@ desc.lpDescription = description; advapi32 = Advapi32.INSTANCE; - serviceManager = openServiceControlManager(null, WINSVC.SC_MANAGER_ALL_ACCESS); + serviceManager = openServiceControlManager(null, Winsvc.SC_MANAGER_ALL_ACCESS); if(serviceManager != null) { service = advapi32.CreateService(serviceManager, serviceName, displayName, - WINSVC.SERVICE_ALL_ACCESS, WINSVC.SERVICE_WIN32_OWN_PROCESS, WINSVC.SERVICE_DEMAND_START, - WINSVC.SERVICE_ERROR_NORMAL, + Winsvc.SERVICE_ALL_ACCESS, WinNT.SERVICE_WIN32_OWN_PROCESS, WinNT.SERVICE_DEMAND_START, + WinNT.SERVICE_ERROR_NORMAL, command, null, null, dep, account, password); if(service != null) { - success = advapi32.ChangeServiceConfig2(service, WINSVC.SERVICE_CONFIG_DESCRIPTION, desc); + success = advapi32.ChangeServiceConfig2(service, Winsvc.SERVICE_CONFIG_DESCRIPTION, desc); advapi32.CloseServiceHandle(service); } advapi32.CloseServiceHandle(serviceManager); @@ -103,14 +150,14 @@ */ public boolean uninstall() { Advapi32 advapi32; - Pointer serviceManager, service; + SC_HANDLE serviceManager, service; boolean success = false; advapi32 = Advapi32.INSTANCE; - serviceManager = openServiceControlManager(null, WINSVC.SC_MANAGER_ALL_ACCESS); + serviceManager = openServiceControlManager(null, Winsvc.SC_MANAGER_ALL_ACCESS); if(serviceManager != null) { - service = advapi32.OpenService(serviceManager, serviceName, WINSVC.SERVICE_ALL_ACCESS); + service = advapi32.OpenService(serviceManager, serviceName, Winsvc.SERVICE_ALL_ACCESS); if(service != null) { success = advapi32.DeleteService(service); @@ -127,15 +174,15 @@ */ public boolean start() { Advapi32 advapi32; - Pointer serviceManager, service; + SC_HANDLE serviceManager, service; boolean success = false; advapi32 = Advapi32.INSTANCE; - serviceManager = openServiceControlManager(null, WINNT.GENERIC_EXECUTE); + serviceManager = openServiceControlManager(null, WinNT.GENERIC_EXECUTE); if(serviceManager != null) { - service = advapi32.OpenService(serviceManager, serviceName, WINNT.GENERIC_EXECUTE); + service = advapi32.OpenService(serviceManager, serviceName, WinNT.GENERIC_EXECUTE); if(service != null) { success = advapi32.StartService(service, 0, null); @@ -153,20 +200,20 @@ */ public boolean stop() throws Exception { Advapi32 advapi32; - Pointer serviceManager, service; - Advapi32.SERVICE_STATUS serviceStatus; + SC_HANDLE serviceManager, service; + SERVICE_STATUS serviceStatus; boolean success = false; advapi32 = Advapi32.INSTANCE; - serviceManager = openServiceControlManager(null, WINNT.GENERIC_EXECUTE); + serviceManager = openServiceControlManager(null, WinNT.GENERIC_EXECUTE); if(serviceManager != null) { - service = advapi32.OpenService(serviceManager, serviceName, WINNT.GENERIC_EXECUTE); + service = advapi32.OpenService(serviceManager, serviceName, WinNT.GENERIC_EXECUTE); if(service != null) { - serviceStatus = new Advapi32.SERVICE_STATUS(); - success = advapi32.ControlService(service, WINSVC.SERVICE_CONTROL_STOP, serviceStatus); + serviceStatus = new SERVICE_STATUS(); + success = advapi32.ControlService(service, Winsvc.SERVICE_CONTROL_STOP, serviceStatus); advapi32.CloseServiceHandle(service); } advapi32.CloseServiceHandle(serviceManager); @@ -180,7 +227,7 @@ */ public void init() { Advapi32 advapi32; - Advapi32.SERVICE_TABLE_ENTRY entry; + SERVICE_TABLE_ENTRY entry; serviceMain = new ServiceMain(); advapi32 = Advapi32.INSTANCE; @@ -188,7 +235,7 @@ entry.lpServiceName = serviceName; entry.lpServiceProc = serviceMain; - advapi32.StartServiceCtrlDispatcher(entry.toArray(2)); + advapi32.StartServiceCtrlDispatcher((SERVICE_TABLE_ENTRY[]) entry.toArray(2)); } /** @@ -198,8 +245,8 @@ * @param access access flags * @return handle to ServiceControlManager or null when failed */ - private Pointer openServiceControlManager(String machine, int access) { - Pointer handle = null; + private SC_HANDLE openServiceControlManager(String machine, int access) { + SC_HANDLE handle = null; Advapi32 advapi32; advapi32 = Advapi32.INSTANCE; @@ -216,12 +263,12 @@ */ private void reportStatus(int status, int win32ExitCode, int waitHint) { Advapi32 advapi32; - Advapi32.SERVICE_STATUS serviceStatus; + SERVICE_STATUS serviceStatus; advapi32 = Advapi32.INSTANCE; - serviceStatus = new Advapi32.SERVICE_STATUS(); - serviceStatus.dwServiceType = WINNT.SERVICE_WIN32_OWN_PROCESS; - serviceStatus.dwControlsAccepted = WINSVC.SERVICE_ACCEPT_STOP | WINSVC.SERVICE_ACCEPT_SHUTDOWN; + serviceStatus = new SERVICE_STATUS(); + serviceStatus.dwServiceType = WinNT.SERVICE_WIN32_OWN_PROCESS; + serviceStatus.dwControlsAccepted = Winsvc.SERVICE_ACCEPT_STOP | Winsvc.SERVICE_ACCEPT_SHUTDOWN; serviceStatus.dwWin32ExitCode = win32ExitCode; serviceStatus.dwWaitHint = waitHint; serviceStatus.dwCurrentState = status; @@ -259,8 +306,8 @@ serviceControl = new ServiceControl(); serviceStatusHandle = advapi32.RegisterServiceCtrlHandlerEx(serviceName, serviceControl, null); - reportStatus(WINSVC.SERVICE_START_PENDING, WINERROR.NO_ERROR, 3000); - reportStatus(WINSVC.SERVICE_RUNNING, WINERROR.NO_ERROR, 0); + reportStatus(Winsvc.SERVICE_START_PENDING, WinError.NO_ERROR, 3000); + reportStatus(Winsvc.SERVICE_RUNNING, WinError.NO_ERROR, 0); onStart(); @@ -270,7 +317,7 @@ } } catch (InterruptedException ex) { } - reportStatus(WINSVC.SERVICE_STOPPED, WINERROR.NO_ERROR, 0); + reportStatus(Winsvc.SERVICE_STOPPED, WinError.NO_ERROR, 0); // Avoid returning from ServiceMain, which will cause a crash // See http://support.microsoft.com/kb/201349, which recommends @@ -296,15 +343,15 @@ */ public int callback(int dwControl, int dwEventType, Pointer lpEventData, Pointer lpContext) { switch(dwControl) { - case WINSVC.SERVICE_CONTROL_STOP: - case WINSVC.SERVICE_CONTROL_SHUTDOWN: - reportStatus(WINSVC.SERVICE_STOP_PENDING, WINERROR.NO_ERROR, 5000); + case Winsvc.SERVICE_CONTROL_STOP: + case Winsvc.SERVICE_CONTROL_SHUTDOWN: + reportStatus(Winsvc.SERVICE_STOP_PENDING, WinError.NO_ERROR, 5000); onStop(); synchronized(waitObject) { waitObject.notifyAll(); } } - return WINERROR.NO_ERROR; + return WinError.NO_ERROR; } } } diff -Nru libjna-java-4.2.2/contrib/platform/build.xml libjna-java-4.4.0/contrib/platform/build.xml --- libjna-java-4.2.2/contrib/platform/build.xml 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/build.xml 2017-03-14 19:31:03.000000000 +0000 @@ -64,31 +64,31 @@ --> - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + - - - + Running platform tests: ${test.src.dir} - - - Saving test results in ${build.test.results.dir.abs} - + + + + Saving test results in ${results.junit} + - + - + @@ -151,23 +150,23 @@ - + - + - - + + - + - + One or more tests failed diff -Nru libjna-java-4.2.2/contrib/platform/nbproject/build-impl.xml libjna-java-4.4.0/contrib/platform/nbproject/build-impl.xml --- libjna-java-4.2.2/contrib/platform/nbproject/build-impl.xml 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/nbproject/build-impl.xml 2017-03-14 19:31:03.000000000 +0000 @@ -12,52 +12,112 @@ - execution - debugging - javadoc - - junit compilation - - junit execution - - junit debugging + - test compilation + - test execution + - test debugging - applet - cleanup ---> - - + --> + + + + + + + + + + ====================== + INITIALIZATION SECTION + ====================== + --> - + + + - + - + + - + + - + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -77,9 +137,13 @@ - + + + + + @@ -89,12 +153,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + Must set src.dir Must set test.src.dir Must set build.dir @@ -115,53 +249,488 @@ - + - - - - + + + + + + + + + + - + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + - - - + + + - + @@ -169,32 +738,56 @@ - + - + + + - + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - + + + + + + + - + @@ -203,305 +796,556 @@ - + + + - + + + + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + - - + =================== + COMPILATION SECTION + =================== + --> + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + - + + + + + + + - + - + Must select some files in the IDE or set javac.includes - - - - - + + - + - - + ==================== + JAR BUILDING SECTION + ==================== + --> + + - - - - - - - - - - - - - To run this application from the command line without Ant, try: - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + - java -cp "${run.classpath.with.dist.jar}" ${main.class} + + + + + + + - - - - - - - - - - - - - - - - - - - - - - To run this application from the command line without Ant, try: - - java -jar "${dist.jar.resolved}" + + + + + + - + + - + ================= + EXECUTION SECTION + ================= + --> + - + + + + Must select one file in the IDE or set run.class + + Must select one file in the IDE or set run.class + + - + ================= + DEBUGGING SECTION + ================= + --> + - + + + + - - + + - - + + 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 - + - + + - + pre NB7.2 profiler integration + --> + + 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 + + + + + - + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + - + - + - + ========================= + TEST COMPILATION SECTION + ========================= + --> + - - + + + + + - + - + - + Must select some files in the IDE or set javac.includes - - - - - + + - + - + - + ======================= + TEST EXECUTION SECTION + ======================= + --> + - - + + - - Some tests failed; see details above. + + Some tests failed; see details above. - - - - + + + + - + Must select some files in the IDE or set test.includes - + + + + Some tests failed; see details above. - - 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. + + - + ======================= + TEST DEBUGGING SECTION + ======================= + --> + 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 + - - + + + + + + - + - + ========================= + APPLET EXECUTION SECTION + ========================= + --> + Must select one file in the IDE or set applet.url @@ -510,11 +1354,11 @@ - + ========================= + APPLET DEBUGGING SECTION + ========================= + --> + Must select one file in the IDE or set applet.url @@ -522,20 +1366,54 @@ - + - - + =============== + CLEANUP SECTION + =============== + --> + + + + + + + + + + + + + + + + + - + - + + + + + + + + + + + + + + + + + + + + diff -Nru libjna-java-4.2.2/contrib/platform/nbproject/project.properties libjna-java-4.4.0/contrib/platform/nbproject/project.properties --- libjna-java-4.2.2/contrib/platform/nbproject/project.properties 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/nbproject/project.properties 2017-03-14 19:31:03.000000000 +0000 @@ -67,3 +67,5 @@ ${build.test.classes.dir} src.dir=src test.src.dir=test +source.encoding=UTF-8 +file.encoding=UTF-8 \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/DesktopWindow.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/DesktopWindow.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/DesktopWindow.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/DesktopWindow.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,76 +1,88 @@ -/* - * Copyright (c) 2015 Andreas "PAX" L\u00FCck, All Rights Reserved - * - * This library is free software; you can - * redistribute it and/or modify it under the terms of the GNU Lesser - * General Public License as published by the Free Software Foundation; - * either version 2.1 of the License, or (at your option) any later - * version.

This library is distributed in the hope that it will be - * useful, but WITHOUT ANY WARRANTY; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform; - -import java.awt.Rectangle; - -import com.sun.jna.platform.win32.WinDef.HWND; - -/** - * Holds some general information about a window. - * - * @author Andreas "PAX" Lück, onkelpax-git[at]yahoo.de - */ -public class DesktopWindow { - private HWND hwnd; - private String title; - private String filePath; - private Rectangle locAndSize; - - /** - * @param hwnd - * The associated window handle for this window. - * @param title - * The title text of the window. - * @param filePath - * The full file path to the main process that created the - * window. - * @param locAndSize - * The window's location on screen and its dimensions. - */ - public DesktopWindow(final HWND hwnd, final String title, - final String filePath, final Rectangle locAndSize) { - this.hwnd = hwnd; - this.title = title; - this.filePath = filePath; - this.locAndSize = locAndSize; - } - - /** - * @return The associated window handle for this window. - */ - public HWND getHWND() { - return hwnd; - } - - /** - * @return The title text of the window. - */ - public String getTitle() { - return title; - } - - /** - * @return The full file path to the main process that created the window. - */ - public String getFilePath() { - return filePath; - } - - /** - * @return The window's location on screen and its dimensions. - */ - public Rectangle getLocAndSize() { - return locAndSize; - } -} +/* + * Copyright (c) 2015 Andreas "PAX" L\u00FCck, 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; + +import java.awt.Rectangle; + +import com.sun.jna.platform.win32.WinDef.HWND; + +/** + * Holds some general information about a window. + * + * @author Andreas "PAX" Lück, onkelpax-git[at]yahoo.de + */ +public class DesktopWindow { + private HWND hwnd; + private String title; + private String filePath; + private Rectangle locAndSize; + + /** + * @param hwnd + * The associated window handle for this window. + * @param title + * The title text of the window. + * @param filePath + * The full file path to the main process that created the + * window. + * @param locAndSize + * The window's location on screen and its dimensions. + */ + public DesktopWindow(final HWND hwnd, final String title, + final String filePath, final Rectangle locAndSize) { + this.hwnd = hwnd; + this.title = title; + this.filePath = filePath; + this.locAndSize = locAndSize; + } + + /** + * @return The associated window handle for this window. + */ + public HWND getHWND() { + return hwnd; + } + + /** + * @return The title text of the window. + */ + public String getTitle() { + return title; + } + + /** + * @return The full file path to the main process that created the window. + */ + public String getFilePath() { + return filePath; + } + + /** + * @return The window's location on screen and its dimensions. + */ + public Rectangle getLocAndSize() { + return locAndSize; + } +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/dnd/DragHandler.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/dnd/DragHandler.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/dnd/DragHandler.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/dnd/DragHandler.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

- * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.dnd; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/dnd/DropHandler.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/dnd/DropHandler.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/dnd/DropHandler.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/dnd/DropHandler.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

- * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.dnd; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/dnd/DropTargetPainter.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/dnd/DropTargetPainter.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/dnd/DropTargetPainter.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/dnd/DropTargetPainter.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

- * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.dnd; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/dnd/GhostedDragImage.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/dnd/GhostedDragImage.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/dnd/GhostedDragImage.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/dnd/GhostedDragImage.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

- * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.dnd; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/EnumConverter.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/EnumConverter.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/EnumConverter.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/EnumConverter.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,17 +1,26 @@ /* * Copyright 2014 Martin Steiger * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * 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; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/EnumUtils.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/EnumUtils.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/EnumUtils.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/EnumUtils.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,17 +1,26 @@ /* * Copyright 2014 Martin Steiger * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * 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; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/FileMonitor.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/FileMonitor.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/FileMonitor.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/FileMonitor.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

- * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; @@ -79,7 +90,7 @@ } public void addWatch(File dir, int mask, boolean recursive) throws IOException { - watched.put(dir, new Integer(mask)); + watched.put(dir, Integer.valueOf(mask)); watch(dir, mask, recursive); } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/FileUtils.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/FileUtils.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/FileUtils.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/FileUtils.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

- * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/KeyboardUtils.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/KeyboardUtils.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/KeyboardUtils.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/KeyboardUtils.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/mac/Carbon.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/mac/Carbon.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/mac/Carbon.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/mac/Carbon.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,24 +1,31 @@ /* * Copyright (c) 2011 Denis Tulskiy * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with this work. If not, see . + * 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.mac; import java.nio.IntBuffer; -import java.util.Arrays; import java.util.List; import com.sun.jna.Library; @@ -33,58 +40,68 @@ * Date: 7/25/11 */ public interface Carbon extends Library { - public static Carbon INSTANCE = (Carbon) Native.loadLibrary("Carbon", Carbon.class); + Carbon INSTANCE = Native.loadLibrary("Carbon", Carbon.class); - public static final int cmdKey = 0x0100; - public static final int shiftKey = 0x0200; - public static final int optionKey = 0x0800; - public static final int controlKey = 0x1000; + int cmdKey = 0x0100; + int shiftKey = 0x0200; + int optionKey = 0x0800; + int controlKey = 0x1000; /** * Obtains the event target reference for the standard toolbox dispatcher * @return event dispatcher reference */ - public Pointer GetEventDispatcherTarget(); + Pointer GetEventDispatcherTarget(); /** * Installs an event handler on a specified event target. */ - public int InstallEventHandler(Pointer inTarget, EventHandlerProcPtr inHandler, int inNumTypes, EventTypeSpec[] inList, Pointer inUserData, PointerByReference outRef); + int InstallEventHandler(Pointer inTarget, EventHandlerProcPtr inHandler, int inNumTypes, EventTypeSpec[] inList, Pointer inUserData, PointerByReference outRef); /** * Registers a global hot key. */ - public int RegisterEventHotKey(int inHotKeyCode, int inHotKeyModifiers, EventHotKeyID.ByValue inHotKeyID, Pointer inTarget, int inOptions, PointerByReference outRef); + int RegisterEventHotKey(int inHotKeyCode, int inHotKeyModifiers, EventHotKeyID.ByValue inHotKeyID, Pointer inTarget, int inOptions, PointerByReference outRef); /** * Obtains a parameter from the specified event. */ - public int GetEventParameter(Pointer inEvent, int inName, int inDesiredType, Pointer outActualType, int inBufferSize, IntBuffer outActualSize, EventHotKeyID outData); + int GetEventParameter(Pointer inEvent, int inName, int inDesiredType, Pointer outActualType, int inBufferSize, IntBuffer outActualSize, EventHotKeyID outData); /** * Removes the specified event handler */ - public int RemoveEventHandler(Pointer inHandlerRef); + int RemoveEventHandler(Pointer inHandlerRef); /** * Unregisters a global hot key. */ - public int UnregisterEventHotKey(Pointer inHotKey); + int UnregisterEventHotKey(Pointer inHotKey); public class EventTypeSpec extends Structure { + public static final List FIELDS = createFieldsOrder("eventClass", "eventKind"); + public int eventClass; public int eventKind; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "eventClass", "eventKind" }); } + + @Override + protected List getFieldOrder() { + return FIELDS; + } } public static class EventHotKeyID extends Structure { + public static final List FIELDS = createFieldsOrder("signature", "id"); + public int signature; public int id; public static class ByValue extends EventHotKeyID implements Structure.ByValue { } - protected List getFieldOrder() { - return Arrays.asList(new String[] { "signature", "id" }); } + + @Override + protected List getFieldOrder() { + return FIELDS; + } } public static interface EventHandlerProcPtr extends Callback { diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/mac/MacFileUtils.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/mac/MacFileUtils.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/mac/MacFileUtils.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/mac/MacFileUtils.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,26 +1,35 @@ /* Copyright (c) 2007-2013 Timothy Wall, 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.mac; import java.io.File; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import com.sun.jna.Library; import com.sun.jna.Native; -import com.sun.jna.Pointer; import com.sun.jna.Structure; import com.sun.jna.ptr.PointerByReference; import com.sun.jna.ptr.ByteByReference; @@ -28,11 +37,12 @@ public class MacFileUtils extends FileUtils { + @Override public boolean hasTrash() { return true; } public interface FileManager extends Library { - public FileManager INSTANCE = (FileManager)Native.loadLibrary("CoreServices", FileManager.class); + FileManager INSTANCE = Native.loadLibrary("CoreServices", FileManager.class); int kFSFileOperationDefaultOptions = 0; int kFSFileOperationsOverwrite = 0x01; @@ -44,12 +54,17 @@ int kFSPathMakeRefDoNotFollowLeafSymlink = 0x01; class FSRef extends Structure { + public static final List FIELDS = createFieldsOrder("hidden"); public byte[] hidden = new byte[80]; - protected List getFieldOrder() { return Arrays.asList(new String[] { "hidden" }); } + + @Override + protected List getFieldOrder() { + return FIELDS; + } } // Deprecated; use trashItemAtURL instead: - // https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSFileManager_Class/Reference/Reference.html#//apple_ref/occ/instm/NSFileManager/trashItemAtURL:resultingItemURL:error: + // https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSFileManager_Class/Reference/Reference.html#//apple_ref/occ/instm/NSFileManager/trashItemAtURL:resultingItemURL:error: int FSRefMakePath(FSRef fsref, byte[] path, int maxPathSize); int FSPathMakeRef(String source, int options, ByteByReference isDirectory); int FSPathMakeRefWithOptions(String source, int options, FSRef fsref, ByteByReference isDirectory); @@ -57,6 +72,7 @@ int FSMoveObjectToTrashSync(FSRef source, FSRef target, int options); } + @Override public void moveToTrash(File[] files) throws IOException { File home = new File(System.getProperty("user.home")); File trash = new File(home, ".Trash"); @@ -67,7 +83,7 @@ for (int i=0;i < files.length;i++) { File src = files[i]; FileManager.FSRef fsref = new FileManager.FSRef(); - int status = FileManager.INSTANCE.FSPathMakeRefWithOptions(src.getAbsolutePath(), + int status = FileManager.INSTANCE.FSPathMakeRefWithOptions(src.getAbsolutePath(), FileManager.kFSPathMakeRefDoNotFollowLeafSymlink, fsref, null); if (status != 0) { diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/mac/SystemB.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/mac/SystemB.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/mac/SystemB.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/mac/SystemB.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,23 +1,30 @@ /* - * Copyright (c) 2015 Daniel Widdis + * Copyright (c) 2015 Daniel Widdis * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with this work. If not, see . + * 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.mac; -import java.util.Arrays; import java.util.List; import com.sun.jna.Library; @@ -33,50 +40,59 @@ */ public interface SystemB extends Library { - public static SystemB INSTANCE = (SystemB) Native.loadLibrary("System", - SystemB.class); + SystemB INSTANCE = Native.loadLibrary("System", SystemB.class); // host_statistics() - static int HOST_LOAD_INFO = 1;// System loading stats - static int HOST_VM_INFO = 2; // Virtual memory stats - static int HOST_CPU_LOAD_INFO = 3;// CPU load stats + int HOST_LOAD_INFO = 1;// System loading stats + int HOST_VM_INFO = 2; // Virtual memory stats + int HOST_CPU_LOAD_INFO = 3;// CPU load stats // host_statistics64() - static int HOST_VM_INFO64 = 4; // 64-bit virtual memory stats + int HOST_VM_INFO64 = 4; // 64-bit virtual memory stats // host_cpu_load_info() - static int CPU_STATE_MAX = 4; - static int CPU_STATE_USER = 0; - static int CPU_STATE_SYSTEM = 1; - static int CPU_STATE_IDLE = 2; - static int CPU_STATE_NICE = 3; + int CPU_STATE_MAX = 4; + int CPU_STATE_USER = 0; + int CPU_STATE_SYSTEM = 1; + int CPU_STATE_IDLE = 2; + int CPU_STATE_NICE = 3; // host_processor_info() flavor - static int PROCESSOR_BASIC_INFO = 1; - static int PROCESSOR_CPU_LOAD_INFO = 2; + int PROCESSOR_BASIC_INFO = 1; + int PROCESSOR_CPU_LOAD_INFO = 2; // Data size - static int UINT64_SIZE = Native.getNativeSize(long.class); - static int INT_SIZE = Native.getNativeSize(int.class); + int UINT64_SIZE = Native.getNativeSize(long.class); + int INT_SIZE = Native.getNativeSize(int.class); public static class HostCpuLoadInfo extends Structure { + public static final List FIELDS = createFieldsOrder("cpu_ticks"); public int cpu_ticks[] = new int[CPU_STATE_MAX]; - + + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "cpu_ticks" }); + return FIELDS; } } public static class HostLoadInfo extends Structure { + public static final List FIELDS = createFieldsOrder("avenrun", "mach_factor"); public int[] avenrun = new int[3]; // scaled by LOAD_SCALE public int[] mach_factor = new int[3]; // scaled by LOAD_SCALE - + + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "avenrun", "mach_factor" }); + return FIELDS; } } public static class VMStatistics extends Structure { + public static final List FIELDS = createFieldsOrder("free_count", "active_count", + "inactive_count", "wire_count", "zero_fill_count", + "reactivations", "pageins", "pageouts", "faults", + "cow_faults", "lookups", "hits", "purgeable_count", + "purges", "speculative_count"); + public int free_count; // # of pages free public int active_count; // # of pages active public int inactive_count; // # of pages inactive @@ -94,16 +110,27 @@ // # of pages speculative (included in free_count) public int speculative_count; + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "free_count", "active_count", - "inactive_count", "wire_count", "zero_fill_count", - "reactivations", "pageins", "pageouts", "faults", - "cow_faults", "lookups", "hits", "purgeable_count", - "purges", "speculative_count" }); + return FIELDS; } } public static class VMStatistics64 extends Structure { + public static final List FIELDS = createFieldsOrder("free_count", "active_count", + "inactive_count", "wire_count", + "zero_fill_count", "reactivations", + "pageins", "pageouts", + "faults", "cow_faults", + "lookups", "hits", + "purges", + "purgeable_count", "speculative_count", + "decompressions", "compressions", + "swapins", "swapouts", + "compressor_page_count", "throttled_count", + "external_page_count", "internal_page_count", + "total_uncompressed_pages_in_compressor"); + public int free_count; // # of pages free public int active_count; // # of pages active public int inactive_count; // # of pages inactive @@ -137,19 +164,7 @@ @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "free_count", "active_count", - "inactive_count", "wire_count", - "zero_fill_count", "reactivations", - "pageins", "pageouts", - "faults", "cow_faults", - "lookups", "hits", - "purges", - "purgeable_count", "speculative_count", - "decompressions", "compressions", - "swapins", "swapouts", - "compressor_page_count", "throttled_count", - "external_page_count", "internal_page_count", - "total_uncompressed_pages_in_compressor" }); + return FIELDS; } } @@ -157,14 +172,23 @@ * The mach_host_self system call returns the calling thread's host name * port. It has an effect equivalent to receiving a send right for the host * port. - * + * * @return the host's name port */ int mach_host_self(); + + /** + * The mach_task_self system call returns the calling thread's task_self + * port. It has an effect equivalent to receiving a send right for the task's + * kernel port. + * + * @return the task's kernel port + */ + int mach_task_self(); /** * The host_page_size function returns the page size for the given host. - * + * * @param machPort * The name (or control) port for the host for which the page * size is desired. @@ -177,7 +201,7 @@ /** * The host_statistics function returns scheduling and virtual memory * statistics concerning the host as specified by hostStat. - * + * * @param machPort * The control port for the host for which information is to be * obtained. @@ -191,13 +215,12 @@ * returned (in natural-sized units). * @return 0 on success; sets errno on failure */ - int host_statistics(int machPort, int hostStat, Structure stats, - IntByReference count); + int host_statistics(int machPort, int hostStat, Structure stats, IntByReference count); /** * The host_statistics64 function returns 64-bit virtual memory statistics * concerning the host as specified by hostStat. - * + * * @param machPort * The control port for the host for which information is to be * obtained. @@ -210,17 +233,16 @@ * returned (in natural-sized units). * @return 0 on success; sets errno on failure */ - int host_statistics64(int machPort, int hostStat, Structure stats, - IntByReference count); + int host_statistics64(int machPort, int hostStat, Structure stats, IntByReference count); /** * The sysctl() function retrieves system information and allows processes * with appropriate privileges to set system information. The information * available from sysctl() consists of integers, strings, and tables. - * + * * The state is described using a "Management Information Base" (MIB) style * name, listed in name, which is a namelen length array of integers. - * + * * The information is copied into the buffer specified by oldp. The size of * the buffer is given by the location specified by oldlenp before the call, * and that location gives the amount of data copied after a successful call @@ -229,18 +251,18 @@ * call supplies as much data as fits in the buffer provided and returns * with the error code ENOMEM. If the old value is not desired, oldp and * oldlenp should be set to NULL. - * + * * The size of the available data can be determined by calling sysctl() with * the NULL argument for oldp. The size of the available data will be * returned in the location pointed to by oldlenp. For some operations, the * amount of space may change often. For these operations, the system * attempts to round up so that the returned size is large enough for a call * to return the data shortly thereafter. - * + * * To set a new value, newp is set to point to a buffer of length newlen * from which the requested value is to be taken. If a new value is not to * be set, newp should be set to NULL and newlen set to 0. - * + * * @param name * MIB array of integers * @param namelen @@ -262,7 +284,7 @@ * The sysctlbyname() function accepts an ASCII representation of the name * and internally looks up the integer name vector. Apart from that, it * behaves the same as the standard sysctl() function. - * + * * @param name * ASCII representation of the MIB name * @param oldp @@ -290,15 +312,15 @@ * to repeatedly request the same variable (the sysctl() function runs in * about a third the time as the same request made via the sysctlbyname() * function). - * + * * The number of elements in the mib array can be determined by calling * sysctlnametomib() with the NULL argument for mibp. - * + * * The sysctlnametomib() function is also useful for fetching mib prefixes. * If size on input is greater than the number of elements written, the * array still contains the additional elements which may be written * programmatically. - * + * * @param name * ASCII representation of the name * @param mibp @@ -309,10 +331,10 @@ * @return 0 on success; sets errno on failure */ int sysctlnametomib(String name, Pointer mibp, IntByReference size); - + /** * The host_processor_info function returns information about processors. - * + * * @param machPort * The control port for the host for which information is to be * obtained. @@ -328,4 +350,20 @@ */ int host_processor_info(int machPort, int flavor, IntByReference procCount, PointerByReference procInfo, IntByReference procInfoCount); + + /** + * The getloadavg() function returns the number of processes in the system + * run queue averaged over various periods of time. Up to nelem samples are + * retrieved and assigned to successive elements of loadavg[]. The system + * imposes a maximum of 3 samples, representing averages over the last 1, 5, + * and 15 minutes, respectively. + * @param loadavg + * An array of doubles which will be filled with the results + * @param nelem + * Number of samples to return + * @return If the load average was unobtainable, -1 is returned; otherwise, + * the number of samples actually retrieved is returned. + * @see getloadavg(3) + */ + int getloadavg(double[] loadavg, int nelem); } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/mac/XAttr.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/mac/XAttr.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/mac/XAttr.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/mac/XAttr.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2014 Reinhard Pointner, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.mac; @@ -23,7 +34,7 @@ interface XAttr extends Library { // load from current image - XAttr INSTANCE = (XAttr) Native.loadLibrary(null, XAttr.class); + XAttr INSTANCE = Native.loadLibrary(null, XAttr.class); // see /usr/include/sys/xattr.h int XATTR_NOFOLLOW = 0x0001; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/mac/XAttrUtil.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/mac/XAttrUtil.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/mac/XAttrUtil.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/mac/XAttrUtil.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2014 Reinhard Pointner, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.mac; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/RasterRangesUtils.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/RasterRangesUtils.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/RasterRangesUtils.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/RasterRangesUtils.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,15 +1,26 @@ /* Copyright (c) 2007 Olivier Chafik, All Rights Reserved * Copyright (c) 2008 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; @@ -30,7 +41,7 @@ /** * Methods that are useful to decompose a raster into a set of rectangles. - * An occupied pixel has two possible meanings, depending on the raster : + * An occupied pixel has two possible meanings, depending on the raster : *

    *
  • if the raster has an alpha layer, occupied means with alpha not null
  • *
  • if the raster doesn't have any alpha layer, occupied means not completely black
  • @@ -45,6 +56,7 @@ }; private static final Comparator COMPARATOR = new Comparator() { + @Override public int compare(Object o1, Object o2) { return ((Rectangle)o1).x - ((Rectangle)o2).x; } @@ -117,7 +129,7 @@ */ public static boolean outputOccupiedRangesOfBinaryPixels(byte[] binaryBits, int w, int h, RangesOutput out) { Set rects = new HashSet(); - Set prevLine = Collections.EMPTY_SET; + Set prevLine = Collections.emptySet(); int scanlineBytes = binaryBits.length / h; for (int row = 0; row < h; row++) { Set curLine = new TreeSet(COMPARATOR); @@ -190,7 +202,7 @@ */ public static boolean outputOccupiedRanges(int[] pixels, int w, int h, int occupationMask, RangesOutput out) { Set rects = new HashSet(); - Set prevLine = Collections.EMPTY_SET; + Set prevLine = Collections.emptySet(); for (int row = 0; row < h; row++) { Set curLine = new TreeSet(COMPARATOR); int idxOffset = row * w; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/unix/LibCAPI.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/unix/LibCAPI.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/unix/LibCAPI.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/unix/LibCAPI.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,101 @@ +/* Copyright (c) 2015 Goldstein Lyor, 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.unix; + +/** + * Note: we are using this "intermediate" API in order to allow + * Linux-like O/S-es to implement the same API, but maybe using a different + * library name + * @author Lyor Goldstein + */ +public interface LibCAPI extends Reboot, Resource { + // see man(2) get/set uid/gid + int getuid(); + int geteuid(); + int getgid(); + int getegid(); + + int setuid(int uid); + int seteuid(int uid); + int setgid(int gid); + int setegid(int gid); + + // see man(2) get/set hostname + int HOST_NAME_MAX = 255; // not including the '\0' + int gethostname(char[] name, int len); + int sethostname(char[] name, int len); + + // see man(2) get/set domainname + int getdomainname(char[] name, int len); + int setdomainname(char[] name, int len); + + /** + * @param name Environment variable name + * @return Returns the value in the environment, or {@code null} if there + * is no match for the name + * @see getenv(3) + */ + String getenv(String name); + + /** + * Update or add a variable in the environment of the calling process. + * @param name Environment variable name + * @param value Required value + * @param overwrite If the environment variable already exists and the + * value of {@code overwrite} is non-zero, the function shall return + * success and the environment shall be updated. If the environment + * variable already exists and the value of {@code overwrite} is zero, the + * function shall return success and the environment shall remain unchanged. + * @return Upon successful completion, zero shall be returned. Otherwise, + * -1 shall be returned, {@code errno} set to indicate the error, and the + * environment shall be unchanged + * @see getenv(3) + */ + int setenv(String name, String value, int overwrite); + + /** + * @param name Environment variable name - If the named variable does not + * exist in the current environment, the environment shall be unchanged + * and the function is considered to have completed successfully. + * @return Upon successful completion, zero shall be returned. Otherwise, + * -1 shall be returned, {@code errno} set to indicate the error, and the + * environment shall be unchanged + * @see getenv(3) + */ + int unsetenv(String name); + + /** + * The getloadavg() function returns the number of processes in the system + * run queue averaged over various periods of time. Up to nelem samples are + * retrieved and assigned to successive elements of loadavg[]. The system + * imposes a maximum of 3 samples, representing averages over the last 1, 5, + * and 15 minutes, respectively. + * @param loadavg An array of doubles which will be filled with the results + * @param nelem Number of samples to return + * @return If the load average was unobtainable, -1 is returned; otherwise, + * the number of samples actually retrieved is returned. + * @see getloadavg(3) + */ + int getloadavg(double[] loadavg, int nelem); +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/unix/LibC.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/unix/LibC.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/unix/LibC.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/unix/LibC.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,36 @@ +/* Copyright (c) 2015 Goldstein Lyor, 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.unix; + +import com.sun.jna.Library; +import com.sun.jna.Native; + +/** + * libc API + * @author Lyor Goldstein + */ +public interface LibC extends LibCAPI, Library { + String NAME = "c"; + LibC INSTANCE = Native.loadLibrary(NAME, LibC.class); +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/unix/Reboot.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/unix/Reboot.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/unix/Reboot.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/unix/Reboot.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,54 @@ +/* Copyright (c) 2015 Goldstein Lyor, 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.unix; + +/** + * Contains definitions related to the {@code reboot} API + * @author Lyor Goldstein + */ +public interface Reboot { + /** Perform a hard reset now. */ + int RB_AUTOBOOT = 0x01234567; + /* Halt the system. */ + int RB_HALT_SYSTEM = 0xcdef0123; + /** Enable reboot using Ctrl-Alt-Delete keystroke. */ + int RB_ENABLE_CAD = 0x89abcdef; + /** Disable reboot using Ctrl-Alt-Delete keystroke. */ + int RB_DISABLE_CAD = 0; + /** Stop system and switch power off if possible. */ + int RB_POWER_OFF = 0x4321fedc; + /** Suspend system using software suspend. */ + int RB_SW_SUSPEND = 0xd000fce2; + /** Reboot system into new kernel. */ + int RB_KEXEC = 0x45584543; + + /** + * Stops/Reboots the machine + * @param cmd The command + * @return If successful, this call never returns. Otherwise, a -1 + * is returned and an error is returned in the global variable {@code errno}. + * @see man 2 reboot + */ + int reboot(int cmd); +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/unix/Resource.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/unix/Resource.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/unix/Resource.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/unix/Resource.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,113 @@ +/* Copyright (c) 2015 Goldstein Lyor, 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.unix; + +import java.util.List; + +import com.sun.jna.Structure; + +/** + * Definitions related to {@code getrlimit}/{@code setrlimit} + * @author Lyor Goldstein + */ +public interface Resource { + /** Per-process CPU limit, in seconds. */ + int RLIMIT_CPU = 0; + + /** Largest file that can be created, in bytes. */ + int RLIMIT_FSIZE = 1; + + /** Maximum size of data segment, in bytes. */ + int RLIMIT_DATA = 2; + + /** Maximum size of stack segment, in bytes. */ + int RLIMIT_STACK = 3; + + /** Largest core file that can be created, in bytes. */ + int RLIMIT_CORE = 4; + + /** + * Largest resident set size, in bytes. This affects swapping; processes + * that are exceeding their resident set size will be more likely to have + * physical memory taken from them. + */ + int RLIMIT_RSS = 5; + + /** Number of open files. */ + int RLIMIT_NOFILE = 7; + + /** Address space limit. */ + int RLIMIT_AS = 9; + + /** Number of processes. */ + int RLIMIT_NPROC = 6; + + /** Locked-in-memory address space. */ + int RLIMIT_MEMLOCK = 8; + + /** Maximum number of file locks. */ + int RLIMIT_LOCKS = 10; + + /** Maximum number of pending signals. */ + int RLIMIT_SIGPENDING = 11; + + /** Maximum bytes in POSIX message queues. */ + int RLIMIT_MSGQUEUE = 12; + + /** + * Maximum nice priority allowed to raise to. Nice levels 19 .. -20 + * correspond to 0 .. 39 values of this resource limit. + */ + int RLIMIT_NICE = 13; + int RLIMIT_RTPRIO = 14; + + /** + * Maximum CPU time in microseconds that a process scheduled under a + * real-time scheduling policy may consume without making a blocking + * system call before being forcibly de-scheduled. + */ + int RLIMIT_RTTIME = 15; + + /** Number of {@code rlimit} values */ + int RLIMIT_NLIMITS = 16; + + public static class Rlimit extends Structure { + public static final List FIELDS = createFieldsOrder("rlim_cur", "rlim_max"); + + /** The current (soft) limit. */ + public long rlim_cur; + + /** The hard limit. */ + public long rlim_max; + + @Override + protected List getFieldOrder() { + return FIELDS; + } + } + + // see man(2) rlimit + int getrlimit(int resource, Rlimit rlim); + int setrlimit(int resource, Rlimit rlim); +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/unix/X11.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/unix/X11.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/unix/X11.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/unix/X11.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

    - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.unix; @@ -17,7 +28,6 @@ import com.sun.jna.Callback; import com.sun.jna.FromNativeContext; -import com.sun.jna.IntegerType; import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.NativeLong; @@ -43,6 +53,7 @@ || (o instanceof Number && ((Number)o).longValue() == X11.None); } + @Override public Object fromNative(Object nativeValue, FromNativeContext context) { if (isNone(nativeValue)) return None; @@ -60,11 +71,13 @@ || (o instanceof Number && ((Number)o).longValue() == X11.None); } + @Override public Object fromNative(Object nativeValue, FromNativeContext context) { if (isNone(nativeValue)) return None; return new XID(((Number)nativeValue).longValue()); } + @Override public String toString() { return "0x" + Long.toHexString(longValue()); } @@ -75,6 +88,7 @@ public Atom() { } public Atom(long id) { super(id); } /** Return constants for predefined Atom values. */ + @Override public Object fromNative(Object nativeValue, FromNativeContext context) { long value = ((Number)nativeValue).longValue(); if (value <= Integer.MAX_VALUE) { @@ -166,6 +180,7 @@ public static final Colormap None = null; public Colormap() { } public Colormap(long id) { super(id); } + @Override public Object fromNative(Object nativeValue, FromNativeContext context) { if (isNone(nativeValue)) return None; @@ -177,6 +192,7 @@ public static final Font None = null; public Font() { } public Font(long id) { super(id); } + @Override public Object fromNative(Object nativeValue, FromNativeContext context) { if (isNone(nativeValue)) return None; @@ -188,6 +204,7 @@ public static final Cursor None = null; public Cursor() { } public Cursor(long id) { super(id); } + @Override public Object fromNative(Object nativeValue, FromNativeContext context) { if (isNone(nativeValue)) return None; @@ -199,6 +216,7 @@ public static final KeySym None = null; public KeySym() { } public KeySym(long id) { super(id); } + @Override public Object fromNative(Object nativeValue, FromNativeContext context) { if (isNone(nativeValue)) return None; @@ -210,6 +228,7 @@ public static final Drawable None = null; public Drawable() { } public Drawable(long id) { super(id); } + @Override public Object fromNative(Object nativeValue, FromNativeContext context) { if (isNone(nativeValue)) return None; @@ -221,6 +240,7 @@ public static final Window None = null; public Window() { } public Window(long id) { super(id); } + @Override public Object fromNative(Object nativeValue, FromNativeContext context) { if (isNone(nativeValue)) return None; @@ -239,6 +259,7 @@ public static final Pixmap None = null; public Pixmap() { } public Pixmap(long id) { super(id); } + @Override public Object fromNative(Object nativeValue, FromNativeContext context) { if (isNone(nativeValue)) return None; @@ -254,6 +275,7 @@ return new VisualID(getPointer().getNativeLong(Native.POINTER_SIZE).longValue()); throw new IllegalStateException("Attempting to retrieve VisualID from a null Visual"); } + @Override public String toString() { return "Visual: VisualID=0x" + Long.toHexString(getVisualID().longValue()); } @@ -267,7 +289,7 @@ /** Definition (incomplete) of the Xext library. */ interface Xext extends Library { - Xext INSTANCE = (Xext)Native.loadLibrary("Xext", Xext.class); + Xext INSTANCE = Native.loadLibrary("Xext", Xext.class); // Shape Kinds int ShapeBounding = 0; int ShapeClip = 1; @@ -285,21 +307,27 @@ /** Definition (incomplete) of the Xrender library. */ interface Xrender extends Library { - Xrender INSTANCE = (Xrender)Native.loadLibrary("Xrender", Xrender.class); + Xrender INSTANCE = Native.loadLibrary("Xrender", Xrender.class); + class XRenderDirectFormat extends Structure { + public static final List FIELDS = createFieldsOrder("red", "redMask", "green", "greenMask", "blue", "blueMask", "alpha", "alphaMask"); public short red, redMask; public short green, greenMask; public short blue, blueMask; public short alpha, alphaMask; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "red", "redMask", "green", "greenMask", "blue", "blueMask", "alpha", "alphaMask" }); + + @Override + protected List getFieldOrder() { + return FIELDS; } } + class PictFormat extends XID { private static final long serialVersionUID = 1L; public static final PictFormat None = null; public PictFormat(long value) { super(value); } public PictFormat() { this(0); } + @Override public Object fromNative(Object nativeValue, FromNativeContext context) { if (isNone(nativeValue)) return None; @@ -307,13 +335,16 @@ } } class XRenderPictFormat extends Structure { + public static final List FIELDS = createFieldsOrder("id", "type", "depth", "direct", "colormap"); public PictFormat id; public int type; public int depth; public XRenderDirectFormat direct; public Colormap colormap; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "id", "type", "depth", "direct", "colormap" }); + + @Override + protected List getFieldOrder() { + return FIELDS; } } int PictTypeIndexed = 0x0; @@ -324,7 +355,7 @@ /** Definition of the Xevie library. */ interface Xevie extends Library { /** Instance of Xevie. Note: This extension has been removed from xorg/xserver on Oct 22, 2008 because it is broken and maintainerless. */ - Xevie INSTANCE = (Xevie)Native.loadLibrary("Xevie", Xevie.class); + Xevie INSTANCE = Native.loadLibrary("Xevie", Xevie.class); int XEVIE_UNMODIFIED = 0; int XEVIE_MODIFIED = 1; // Bool XevieQueryVersion (Display* display, int* major_version, int* minor_version); @@ -341,7 +372,7 @@ /** Definition of the XTest library. */ interface XTest extends Library { - XTest INSTANCE = (XTest)Native.loadLibrary("Xtst", XTest.class);///usr/lib/libxcb-xtest.so.0 + XTest INSTANCE = Native.loadLibrary("Xtst", XTest.class);///usr/lib/libxcb-xtest.so.0 boolean XTestQueryExtension(Display display, IntByReference event_basep, IntByReference error_basep, IntByReference majorp, IntByReference minorp); boolean XTestCompareCursorWithWindow(Display display, Window window, Cursor cursor); boolean XTestCompareCurrentCursorWithWindow(Display display, Window window); @@ -361,23 +392,29 @@ } class XInputClassInfoByReference extends Structure implements Structure.ByReference { + public static final List FIELDS = createFieldsOrder("input_class", "event_type_base"); public byte input_class; public byte event_type_base; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "input_class", "event_type_base" }); + + @Override + protected List getFieldOrder() { + return FIELDS; } } class XDeviceByReference extends Structure implements Structure.ByReference { + public static final List FIELDS = createFieldsOrder("device_id", "num_classes", "classes"); public XID device_id; public int num_classes; public XInputClassInfoByReference classes; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "device_id", "num_classes", "classes" }); + + @Override + protected List getFieldOrder() { + return FIELDS; } } - X11 INSTANCE = (X11)Native.loadLibrary("X11", X11.class); + X11 INSTANCE = Native.loadLibrary("X11", X11.class); /* typedef struct { @@ -394,6 +431,9 @@ } XWMHints; */ class XWMHints extends Structure { + public static final List FIELDS = createFieldsOrder( + "flags", "input", "initial_state", "icon_pixmap", "icon_window", "icon_x", "icon_y", "icon_mask", "window_group"); + public NativeLong flags; public boolean input; public int initial_state; @@ -402,8 +442,9 @@ public int icon_x, icon_y; public Pixmap icon_mask; public XID window_group; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "flags", "input", "initial_state", "icon_pixmap", "icon_window", "icon_x", "icon_y", "icon_mask", "window_group" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } @@ -416,12 +457,15 @@ } XTextProperty; */ class XTextProperty extends Structure { + public static final List FIELDS = createFieldsOrder("value", "encoding", "format", "nitems"); public String value; public Atom encoding; public int format; public NativeLong nitems; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "value", "encoding", "format", "nitems" }); + + @Override + protected List getFieldOrder() { + return FIELDS; } } @@ -442,23 +486,41 @@ } XSizeHints; */ class XSizeHints extends Structure { + public static class Aspect extends Structure { + public static final List FIELDS = createFieldsOrder("x", "y"); + public int x; // numerator + public int y; // denominator + @Override + protected List getFieldOrder() { + return FIELDS; + } + } + + public static final List FIELDS = createFieldsOrder( + "flags", + "x", "y", + "width", "height", + "min_width", "min_height", + "max_width", "max_height", + "width_inc", "height_inc", + "min_aspect", "max_aspect", + "base_width", "base_height", + "win_gravity"); + public NativeLong flags; public int x, y; public int width, height; public int min_width, min_height; public int max_width, max_height; public int width_inc, height_inc; - public static class Aspect extends Structure { - public int x; // numerator - public int y; // denominator - protected List getFieldOrder() { - return Arrays.asList(new String[] { "x", "y" }); } - } + public Aspect min_aspect, max_aspect; public int base_width, base_height; public int win_gravity; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "flags", "x", "y", "width", "height", "min_width", "min_height", "max_width", "max_height", "width_inc", "height_inc", "min_aspect", "max_aspect", "base_width", "base_height", "win_gravity" }); } + @Override + protected List getFieldOrder() { + return FIELDS; + } } /* @@ -491,6 +553,18 @@ } XWindowAttributes; */ class XWindowAttributes extends Structure { + public static final List FIELDS = createFieldsOrder( + "x", "y", + "width", "height", + "border_width", + "depth", "visual", "root", "c_class", + "bit_gravity", "win_gravity", + "backing_store", "backing_planes", "backing_pixel", + "save_under", "colormap", + "map_installed", "map_state", + "all_event_masks", "your_event_mask", "do_not_propagate_mask", + "override_redirect", "screen"); + public int x, y; public int width, height; public int border_width; @@ -512,8 +586,9 @@ public NativeLong do_not_propagate_mask; public boolean override_redirect; public Screen screen; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "x", "y", "width", "height", "border_width", "depth", "visual", "root", "c_class", "bit_gravity", "win_gravity", "backing_store", "backing_planes", "backing_pixel", "save_under", "colormap", "map_installed", "map_state", "all_event_masks", "your_event_mask", "do_not_propagate_mask", "override_redirect", "screen" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } @@ -537,6 +612,15 @@ } XSetWindowAttributes; */ class XSetWindowAttributes extends Structure { + public static final List FIELDS = createFieldsOrder( + "background_pixmap", "background_pixel", + "border_pixmap", "border_pixel", + "bit_gravity", "win_gravity", + "backing_store", "backing_planes", "backing_pixel", + "save_under", + "event_mask", "do_not_propagate_mask", + "override_redirect", "colormap", "cursor"); + public Pixmap background_pixmap; public NativeLong background_pixel; public Pixmap border_pixmap; @@ -552,8 +636,9 @@ public boolean override_redirect; public Colormap colormap; public Cursor cursor; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "background_pixmap", "background_pixel", "border_pixmap", "border_pixel", "bit_gravity", "win_gravity", "backing_store", "backing_planes", "backing_pixel", "save_under", "event_mask", "do_not_propagate_mask", "override_redirect", "colormap", "cursor" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } @@ -587,6 +672,9 @@ int VisualAllMask = 0x1FF; class XVisualInfo extends Structure { + public static final List FIELDS = createFieldsOrder( + "visual", "visualid", "screen", "depth", "c_class", "red_mask", "green_mask", "blue_mask", "colormap_size", "bits_per_rgb"); + public Visual visual; public VisualID visualid; public int screen; @@ -597,14 +685,17 @@ public NativeLong blue_mask; public int colormap_size; public int bits_per_rgb; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "visual", "visualid", "screen", "depth", "c_class", "red_mask", "green_mask", "blue_mask", "colormap_size", "bits_per_rgb" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } class XPoint extends Structure { + public static final List FIELDS = createFieldsOrder("x", "y"); public short x, y; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "x", "y" }); + @Override + protected List getFieldOrder() { + return FIELDS; } public XPoint() { this((short)0, (short)0); } public XPoint(short x, short y) { @@ -613,10 +704,13 @@ } } class XRectangle extends Structure { + public static final List FIELDS = createFieldsOrder("x", "y", "width", "height"); + public short x, y; public short width, height; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "x", "y", "width", "height" }); + @Override + protected List getFieldOrder() { + return FIELDS; } public XRectangle() { this((short)0, (short)0, (short)0, (short)0); } public XRectangle(short x, short y, short width, short height) { @@ -712,6 +806,10 @@ String icon_name, String[] argv, int argc, XSizeHints normal_hints, Pointer wm_hints, Pointer class_hints); + + int XSetWMProtocols(Display display, Window window, Atom[] atom, int count); + int XGetWMProtocols(Display display, Window w, PointerByReference protocols_return, IntByReference count_return); + int XFree(Pointer data); Window XCreateSimpleWindow(Display display, Window parent, int x, int y, int width, int height, int border_width, @@ -761,7 +859,7 @@ * without I/O if there are events already in the queue. XEventsQueued * with mode QueuedAfterFlush is identical in behavior to * XPending. XEventsQueued with mode QueuedAlready is identical to the - * XQLength function. + * XQLength function. * @param display target Display * @param mode QueuedAlready, QueuedAfterFlush, or QueuedAfterReading * @return status @@ -783,6 +881,18 @@ Pixmap XCreatePixmap(Display display, Drawable drawable, int width, int height, int depth); int XFreePixmap(Display display, Pixmap pixmap); class XGCValues extends Structure { + public static final List FIELDS = createFieldsOrder( + "function", "plane_mask", + "foreground", "background", + "line_width", "line_style", + "cap_style", "join_style", + "fill_style", "fill_rule", + "arc_mode", "tile", "stipple", + "ts_x_origin", "ts_y_origin", + "font", "subwindow_mode", "graphics_exposures", + "clip_x_origin", "clip_y_origin", "clip_mask", + "dash_offset", "dashes"); + public int function; /* logical operation */ public NativeLong plane_mask;/* plane mask */ public NativeLong foreground;/* foreground pixel */ @@ -806,8 +916,9 @@ public Pixmap clip_mask; /* bitmap clipping; other calls for rects */ public int dash_offset; /* patterned/dashed line information */ public byte dashes; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "function", "plane_mask", "foreground", "background", "line_width", "line_style", "cap_style", "join_style", "fill_style", "fill_rule", "arc_mode", "tile", "stipple", "ts_x_origin", "ts_y_origin", "font", "subwindow_mode", "graphics_exposures", "clip_x_origin", "clip_y_origin", "clip_mask", "dash_offset", "dashes" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } GC XCreateGC(Display display, Drawable drawable, NativeLong mask, XGCValues values); @@ -840,11 +951,11 @@ int XGetWindowAttributes(Display display, Window window, XWindowAttributes attributes); int XChangeWindowAttributes(Display display, Window window, NativeLong valuemask, XSetWindowAttributes attributes); // Status XGetGeometry(Display *display, Drawable d, Window *root_return, int *x_return, int *y_return, unsigned int *width_return, - // unsigned int *height_return, unsigned int *border_width_return, unsigned int *depth_return); + // unsigned int *height_return, unsigned int *border_width_return, unsigned int *depth_return); int XGetGeometry(Display display, Drawable d, WindowByReference w, IntByReference x, IntByReference y, IntByReference width, IntByReference heigth, IntByReference border_width, IntByReference depth); // Bool XTranslateCoordinates(Display *display, Window src_w, dest_w, int src_x, int src_y, - // int *dest_x_return, int *dest_y_return, Window *child_return); + // int *dest_x_return, int *dest_y_return, Window *child_return); 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); @@ -1429,13 +1540,15 @@ } public static class XAnyEvent extends Structure { + public static final List FIELDS = createFieldsOrder("type", "serial", "send_event", "display", "window"); public int type; public NativeLong serial; // # of last request processed by server public int send_event; // true if this came from a SendEvent request public Display display; // Display the event was read from public Window window; // window on which event was requested in event mask - protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } @@ -1453,8 +1566,9 @@ public int state; // key or button mask public int keycode; // detail public int same_screen; // same screen flag + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "root", "subwindow", "time", "x", "y", "x_root", "y_root", "state", "keycode", "same_screen" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "root", "subwindow", "time", "x", "y", "x_root", "y_root", "state", "keycode", "same_screen" }); } } @@ -1472,8 +1586,9 @@ public int state; // key or button mask public int button; // detail public int same_screen; // same screen flag + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "root", "subwindow", "time", "x", "y", "x_root", "y_root", "state", "button", "same_screen" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "root", "subwindow", "time", "x", "y", "x_root", "y_root", "state", "button", "same_screen" }); } } @@ -1492,8 +1607,9 @@ public Atom message_type; public int format; public Data data; + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "message_type", "format", "data" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "message_type", "format", "data" }); } public static class Data extends Union { @@ -1517,8 +1633,9 @@ public int state; // key or button mask public byte is_hint; // detail public int same_screen; // same screen flag + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "root", "subwindow", "time", "x", "y", "x_root", "y_root", "state", "is_hint", "same_screen" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "root", "subwindow", "time", "x", "y", "x_root", "y_root", "state", "is_hint", "same_screen" }); } } @@ -1545,8 +1662,9 @@ public int same_screen; // same screen flag public int focus; // boolean focus public int state; // key or button mask + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "root", "subwindow", "time", "x", "y", "x_root", "y_root", "mode", "detail", "same_screen", "focus", "state" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "root", "subwindow", "time", "x", "y", "x_root", "y_root", "mode", "detail", "same_screen", "focus", "state" }); } } @@ -1569,8 +1687,9 @@ * NotifyNonlinear,NotifyNonlinearVirtual, NotifyPointer, * NotifyPointerRoot, NotifyDetailNone */ + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "mode", "detail" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "mode", "detail" }); } } @@ -1589,8 +1708,9 @@ public int x, y; public int width, height; public int count; // if non-zero, at least this many more + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "x", "y", "width", "height", "count" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "x", "y", "width", "height", "count" }); } } @@ -1605,8 +1725,9 @@ public int count; // if non-zero, at least this many more public int major_code; // core is CopyArea or CopyPlane public int minor_code; // not defined in the core + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "drawable", "x", "y", "width", "height", "count", "major_code", "minor_code" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "drawable", "x", "y", "width", "height", "count", "major_code", "minor_code" }); } } @@ -1618,8 +1739,9 @@ public Drawable drawable; public int major_code; // core is CopyArea or CopyPlane public int minor_code; // not defined in the core + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "drawable", "major_code", "minor_code" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "drawable", "major_code", "minor_code" }); } } @@ -1630,8 +1752,9 @@ public Display display; // Display the event was read from public Window window; public int state; // Visibility state + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "state" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "state" }); } } @@ -1646,8 +1769,9 @@ public int width, height; // size of window public int border_width; // border width public int override_redirect; // creation should be overridden + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "parent", "window", "x", "y", "width", "height", "border_width", "override_redirect" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "parent", "window", "x", "y", "width", "height", "border_width", "override_redirect" }); } } @@ -1658,6 +1782,7 @@ public Display display; // Display the event was read from public Window event; public Window window; + @Override protected List getFieldOrder() { return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "event", "window" }); } } @@ -1670,6 +1795,7 @@ public Window event; public Window window; public int from_configure; + @Override protected List getFieldOrder() { return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "event", "window", "from_configure" }); } @@ -1683,6 +1809,7 @@ public Window event; public Window window; public int override_redirect; // boolean, is override set... + @Override protected List getFieldOrder() { return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "event", "window", "override_redirect" }); } @@ -1695,6 +1822,7 @@ public Display display; // Display the event was read from public Window parent; public Window window; + @Override protected List getFieldOrder() { return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "parent", "window" }); } @@ -1710,6 +1838,7 @@ public Window parent; public int x, y; public int override_redirect; + @Override protected List getFieldOrder() { return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "event", "window", "parent", "x", "y", "override_redirect" }); } @@ -1727,6 +1856,7 @@ public int border_width; public Window above; public int override_redirect; + @Override protected List getFieldOrder() { return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "event", "window", "x", "y", "width", "height", "border_width", "above", "override_redirect" }); } @@ -1740,6 +1870,7 @@ public Window event; public Window window; public int x, y; + @Override protected List getFieldOrder() { return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "event", "window", "x", "y" }); } @@ -1752,8 +1883,9 @@ public Display display; // Display the event was read from public Window window; public int width, height; + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "width", "height" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "width", "height" }); } } @@ -1770,6 +1902,7 @@ public Window above; public int detail; // Above, Below, TopIf, BottomIf, Opposite public NativeLong value_mask; + @Override protected List getFieldOrder() { return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "parent", "window", "x", "y", "width", "height", "border_width", "above", "detail", "value_mask" }); } @@ -1783,8 +1916,9 @@ public Window event; public Window window; public int place; // PlaceOnTop, PlaceOnBottom + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "event", "window", "place" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "event", "window", "place" }); } } @@ -1796,8 +1930,9 @@ public Window parent; public Window window; public int place; // PlaceOnTop, PlaceOnBottom + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "parent", "window", "place" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "parent", "window", "place" }); } } @@ -1810,8 +1945,9 @@ public Atom atom; public NativeLong time; public int state; // NewValue, Deleted + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "atom", "time", "state" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "atom", "time", "state" }); } } @@ -1823,8 +1959,9 @@ public Window window; public Atom selection; public NativeLong time; + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "selection", "time" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "selection", "time" }); } } @@ -1839,8 +1976,9 @@ public Atom target; public Atom property; public NativeLong time; + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "owner", "requestor", "selection", "target", "property", "time" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "owner", "requestor", "selection", "target", "property", "time" }); } } @@ -1854,8 +1992,9 @@ public Atom target; public Atom property; // ATOM or None public NativeLong time; + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "requestor", "selection", "target", "property", "time" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "requestor", "selection", "target", "property", "time" }); } } @@ -1868,8 +2007,9 @@ public Colormap colormap; // COLORMAP or None public int c_new; // C++ public int state; // ColormapInstalled, ColormapUninstalled + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "colormap", "c_new", "state" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "colormap", "c_new", "state" }); } } @@ -1882,8 +2022,9 @@ public int request; // one of MappingModifier, MappingKeyboard, MappingPointer public int first_keycode; // first keycode public int count; // defines range of change w. first_keycode*/ + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "request", "first_keycode", "count" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "request", "first_keycode", "count" }); } } @@ -1895,8 +2036,9 @@ public byte request_code; // Major op-code of failed request public byte minor_code; // Minor op-code of failed request public XID resourceid; // resource id + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "display", "serial", "error_code", "request_code", "minor_code", "resourceid" }); + return Arrays.asList(new String[] { "type", "display", "serial", "error_code", "request_code", "minor_code", "resourceid" }); } } @@ -1908,8 +2050,9 @@ public Display display; // Display the event was read from public Window window; public byte key_vector[] = new byte[32]; + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "key_vector" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "key_vector" }); } } @@ -1990,7 +2133,7 @@ /* * KeySyms, Keycodes, Keymaps */ - + String XKeysymToString(KeySym keysym); KeySym XStringToKeysym(String string); byte XKeysymToKeycode(Display display, KeySym keysym); @@ -2044,6 +2187,19 @@ */ int XUngrabKeyboard(Display display, NativeLong time); + /** + * The XFetchName() function returns the name of the specified window. If it succeeds, it returns a nonzero status; + * otherwise, no name has been set for the window, and it returns zero. If the WM_NAME property has not been set for this + * window, XFetchName() sets window_name_return to NULL. If the data returned by the server is in the Latin Portable Character + * Encoding, then the returned string is in the Host Portable Character Encoding. Otherwise, the result is implementation + * dependent. When finished with it, a client must free the window name string using XFree(). + * @param display Specifies the connection to the X server. + * @param window Specifies the window. + * @param window_name_return Returns the window name, which is a null-terminated string. + * @return Integer. Nonzero = success, zero = no name has been set. + */ + int XFetchName(Display display, Window window, PointerByReference window_name_return); + //int XChangeKeyboardMapping(Display display, int first_keycode, int keysyms_per_keycode, KeySym *keysyms, int num_codes); /** Defines the symbols for the specified number of KeyCodes starting with * first_keycode. The symbols for KeyCodes outside this range remain @@ -2204,11 +2360,12 @@ class XModifierKeymapRef extends Structure implements Structure.ByReference{ public int max_keypermod; /* The server's max # of keys per modifier */ public Pointer modifiermap; /* An 8 by max_keypermod array of modifiers */ + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "max_keypermod", "modifiermap" }); + return Arrays.asList(new String[] { "max_keypermod", "modifiermap" }); } } - + class XKeyboardControlRef extends Structure implements Structure.ByReference { /** Volume for key clicks between 0 (off) and 100 (loud) inclusive, if possible. A setting of -1 restores the default. */ public int key_click_percent; @@ -2227,10 +2384,12 @@ /** AutoRepeatModeOff, AutoRepeatModeOn, AutoRepeatModeDefault. */ public int auto_repeat_mode; + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "key_click_percent", "bell_percent", "bell_pitch", "bell_duration", "led", "led_mode", "key", "auto_repeat_mode" }); + return Arrays.asList(new String[] { "key_click_percent", "bell_percent", "bell_pitch", "bell_duration", "led", "led_mode", "key", "auto_repeat_mode" }); } + @Override public String toString() { return "XKeyboardControlByReference{" + "key_click_percent=" + key_click_percent + @@ -2261,10 +2420,12 @@ /** Bit vector. Each bit set to 1 indicates that auto-repeat is enabled for the corresponding key. The vector is represented as 32 bytes. Byte N (from 0) contains the bits for keys 8N to 8N + 7 with the least significant bit in the byte representing key 8N. */ public byte auto_repeats[] = new byte[32]; + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "key_click_percent", "bell_percent", "bell_pitch", "bell_duration", "led_mask", "global_auto_repeat", "auto_repeats" }); + return Arrays.asList(new String[] { "key_click_percent", "bell_percent", "bell_pitch", "bell_duration", "led_mask", "global_auto_repeat", "auto_repeats" }); } + @Override public String toString() { return "XKeyboardStateByReference{" + "key_click_percent=" + key_click_percent + diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/AccCtrl.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/AccCtrl.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/AccCtrl.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/AccCtrl.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,15 +1,25 @@ /* Copyright (c) 2015 Adam Marcionek, All Rights Reserved * - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Advapi32.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Advapi32.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Advapi32.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Advapi32.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,808 +1,1158 @@ /* Copyright (c) 2010 Daniel Doubrovkine, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.Native; import com.sun.jna.Pointer; import com.sun.jna.Structure; -import com.sun.jna.WString; -import com.sun.jna.platform.win32.WinBase.SECURITY_ATTRIBUTES; import com.sun.jna.platform.win32.WinBase.FE_EXPORT_FUNC; import com.sun.jna.platform.win32.WinBase.FE_IMPORT_FUNC; +import com.sun.jna.platform.win32.WinBase.PROCESS_INFORMATION; +import com.sun.jna.platform.win32.WinBase.SECURITY_ATTRIBUTES; +import com.sun.jna.platform.win32.WinBase.STARTUPINFO; +import com.sun.jna.platform.win32.WinDef.BOOLByReference; +import com.sun.jna.platform.win32.WinDef.DWORD; +import com.sun.jna.platform.win32.WinDef.DWORDByReference; +import com.sun.jna.platform.win32.WinDef.ULONG; +import com.sun.jna.platform.win32.WinNT.ACL; +import com.sun.jna.platform.win32.WinNT.GENERIC_MAPPING; import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.platform.win32.WinNT.HANDLEByReference; +import com.sun.jna.platform.win32.WinNT.PACLByReference; +import com.sun.jna.platform.win32.WinNT.PRIVILEGE_SET; import com.sun.jna.platform.win32.WinNT.PSID; import com.sun.jna.platform.win32.WinNT.PSIDByReference; +import com.sun.jna.platform.win32.WinNT.SECURITY_DESCRIPTOR; +import com.sun.jna.platform.win32.WinNT.SECURITY_DESCRIPTOR_RELATIVE; import com.sun.jna.platform.win32.WinReg.HKEY; import com.sun.jna.platform.win32.WinReg.HKEYByReference; +import com.sun.jna.platform.win32.Winsvc.ChangeServiceConfig2Info; import com.sun.jna.platform.win32.Winsvc.SC_HANDLE; import com.sun.jna.platform.win32.Winsvc.SERVICE_STATUS; import com.sun.jna.platform.win32.Winsvc.SERVICE_STATUS_PROCESS; import com.sun.jna.ptr.IntByReference; import com.sun.jna.ptr.LongByReference; import com.sun.jna.ptr.PointerByReference; +import com.sun.jna.ptr.ShortByReference; import com.sun.jna.win32.StdCallLibrary; import com.sun.jna.win32.W32APIOptions; -import static com.sun.jna.platform.win32.WinDef.BOOLByReference; -import static com.sun.jna.platform.win32.WinDef.DWORD; -import static com.sun.jna.platform.win32.WinDef.DWORDByReference; -import static com.sun.jna.platform.win32.WinDef.ULONG; -import static com.sun.jna.platform.win32.WinNT.GENERIC_MAPPING; -import static com.sun.jna.platform.win32.WinNT.PRIVILEGE_SET; - /** * Advapi32.dll Interface. * * @author dblock[at]dblock.org */ public interface Advapi32 extends StdCallLibrary { - Advapi32 INSTANCE = (Advapi32) Native.loadLibrary("Advapi32", - Advapi32.class, W32APIOptions.UNICODE_OPTIONS); + Advapi32 INSTANCE = Native.loadLibrary("Advapi32", Advapi32.class, W32APIOptions.DEFAULT_OPTIONS); + + int MAX_KEY_LENGTH = 255; + int MAX_VALUE_NAME = 16383; + + int RRF_RT_ANY = 0x0000ffff; + int RRF_RT_DWORD = 0x00000018; + int RRF_RT_QWORD = 0x00000048; + int RRF_RT_REG_BINARY = 0x00000008; + int RRF_RT_REG_DWORD = 0x00000010; + int RRF_RT_REG_EXPAND_SZ = 0x00000004; + int RRF_RT_REG_MULTI_SZ = 0x00000020; + int RRF_RT_REG_NONE = 0x00000001; + int RRF_RT_REG_QWORD = 0x00000040; + int RRF_RT_REG_SZ = 0x00000002; + + /** + * LOGON_WITH_PROFILE: 0x00000001
    + * Log on, then load the user profile in the HKEY_USERS registry key.
    + * The function returns after the profile is loaded.
    + * Loading the profile can be time-consuming, so it is best to use this + * value only if you must access the information in the HKEY_CURRENT_USER + * registry key.
    + * Windows Server 2003: The profile is unloaded after the new process is + * terminated, whether or not it has created child processes.
    + * Windows XP: The profile is unloaded after the new process and all child + * processes it has created are terminated.
    + */ + int LOGON_WITH_PROFILE = 0x00000001; + + /** + * LOGON_NETCREDENTIALS_ONLY: 0x00000002
    + * Log on, but use the specified credentials on the network only.
    + * The new process uses the same token as the caller, but the system creates + * a new logon session within LSA, and the process uses the specified + * credentials as the default credentials.
    + * This value can be used to create a process that uses a different set of + * credentials locally than it does remotely.
    + * This is useful in inter-domain scenarios where there is no trust + * relationship.
    + * The system does not validate the specified credentials.
    + * Therefore, the process can start, but it may not have access to network + * resources. + */ + int LOGON_NETCREDENTIALS_ONLY = 0x00000002; + + /** + * Retrieves the name of the user associated with the current thread. + * http://msdn.microsoft.com/en-us/library/ms724432(VS.85).aspx + * + * @param buffer + * Buffer to receive the user's logon name. + * @param len + * On input, the size of the buffer, on output the number of + * characters copied into the buffer, including the terminating + * null character. + * @return True if succeeded. + */ + boolean GetUserNameW(char[] buffer, IntByReference len); + + /** + * Accepts the name of a system and anaccount as input and retrieves a + * security identifier (SID) for the account and the name of the domain on + * which the account was found. + * http://msdn.microsoft.com/en-us/library/aa379159(VS.85).aspx + * + * @param lpSystemName + * Specifies the name of the system. + * @param lpAccountName + * Specifies the account name. + * @param Sid + * Receives the SID structure that corresponds to the account + * name pointed to by the lpAccountName parameter. + * @param cbSid + * On input, this value specifies the size, in bytes, of the Sid + * buffer. If the function fails because the buffer is too small + * or if cbSid is zero, this variable receives the required + * buffer size. + * @param ReferencedDomainName + * Receives the name of the domain where the account name is + * found. + * @param cchReferencedDomainName + * On input, this value specifies the size, in TCHARs, of the + * ReferencedDomainName buffer. If the function fails because the + * buffer is too small, this variable receives the required + * buffer size, including the terminating null character. + * @param peUse + * SID_NAME_USE enumerated type that indicates the type of the + * account when the function returns. + * @return True if the function was successful, False otherwise. + */ + boolean LookupAccountName(String lpSystemName, String lpAccountName, + PSID Sid, IntByReference cbSid, char[] ReferencedDomainName, + IntByReference cchReferencedDomainName, PointerByReference peUse); + + /** + * Retrieves the name of the account for this SID and the name of the first + * domain on which this SID is found. + * + * @param lpSystemName + * Specifies the target computer. + * @param Sid + * The SID to look up. + * @param lpName + * Buffer that receives a null-terminated string that contains + * the account name that corresponds to the lpSid parameter. + * @param cchName + * On input, specifies the size, in TCHARs, of the lpName buffer. + * If the function fails because the buffer is too small or if + * cchName is zero, cchName receives the required buffer size, + * including the terminating null character. + * @param ReferencedDomainName + * Pointer to a buffer that receives a null-terminated string + * that contains the name of the domain where the account name + * was found. + * @param cchReferencedDomainName + * On input, specifies the size, in TCHARs, of the + * lpReferencedDomainName buffer. If the function fails because + * the buffer is too small or if cchReferencedDomainName is zero, + * cchReferencedDomainName receives the required buffer size, + * including the terminating null character. + * @param peUse + * Pointer to a variable that receives a SID_NAME_USE value that + * indicates the type of the account. + * @return If the function succeeds, the function returns nonzero. If the + * function fails, it returns zero. To get extended error + * information, call GetLastError. + */ + boolean LookupAccountSid(String lpSystemName, PSID Sid, + char[] lpName, IntByReference cchName, char[] ReferencedDomainName, + IntByReference cchReferencedDomainName, PointerByReference peUse); + + /** + * Convert a security identifier (SID) to a string format suitable for + * display, storage, or transmission. + * + * @param Sid + * The SID structure to be converted. + * @param StringSid + * Pointer to a variable that receives a pointer to a + * null-terminated SID string. To free the returned buffer, call + * the LocalFree function. + * @return {@code true} if the function was successful - call {@code GetLastError()} + * to check failure reason + * @see ConvertSidToStringSid + */ + boolean ConvertSidToStringSid(PSID Sid, PointerByReference StringSid); + + /** + * Convert a string-format security identifier (SID) into a valid, + * functional SID. + * + * + * @param StringSid + * The string-format SID to convert. + * @param Sid + * Receives a pointer to the converted SID. To free the returned buffer, call + * the LocalFree function. + * @return {@code true} if the function was successful - call {@code GetLastError()} + * to check failure reason + * @see ConvertStringSidToSid + */ + boolean ConvertStringSidToSid(String StringSid, PSIDByReference Sid); + + /** + * Returns the length, in bytes, of a valid security identifier (SID). + * http://msdn.microsoft.com/en-us/library/aa446642(VS.85).aspx + * + * @param pSid + * A pointer to the SID structure whose length is returned. + * @return Length of the SID. + */ + int GetLengthSid(PSID pSid); + + /** + * The IsValidSid function validates a security identifier (SID) by + * verifying that the revision number is within a known range, and that the + * number of subauthorities is less than the maximum. + * + * @param pSid + * Pointer to the SID structure to validate. This parameter + * cannot be NULL. + * @return If the SID structure is valid, the return value is nonzero. If + * the SID structure is not valid, the return value is zero. There + * is no extended error information for this function; do not call + * GetLastError. + */ + boolean IsValidSid(PSID pSid); + + /** + * he EqualSid function tests two security identifier (SID) values for equality. + * Two SIDs must match exactly to be considered equal. + * @param pSid1 + * A pointer to the first SID structure to compare. This structure is assumed to be valid. + * @param pSid2 + * A pointer to the second SID structure to compare. This structure is assumed to be valid. + * @return If the SID structures are equal, the return value is nonzero. + * If the SID structures are not equal, the return value is zero. To get extended error + * information, call GetLastError. + * If either SID structure is not valid, the return value is undefined. + */ + boolean EqualSid(PSID pSid1, PSID pSid2); + + /** + * Compares a SID to a well known SID and returns TRUE if they match. + * + * @param pSid + * SID to test. + * @param wellKnownSidType + * Member of the WELL_KNOWN_SID_TYPE enumeration to compare with + * the SID at pSid. + * @return True if the SID is of a given well known type, false otherwise. + */ + boolean IsWellKnownSid(PSID pSid, int wellKnownSidType); - public static final int MAX_KEY_LENGTH = 255; - public static final int MAX_VALUE_NAME = 16383; + /** + * The CreateWellKnownSid function creates a SID for predefined aliases. + * + * @param wellKnownSidType + * Member of the WELL_KNOWN_SID_TYPE enumeration that specifies + * what the SID will identify. + * @param domainSid + * Pointer to a SID that identifies the domain control to use + * when creating the SID. Pass NULL to use the local computer. + * @param pSid + * Pointer to memory where CreateWellKnownSid will store the new + * SID. + * @param cbSid + * Pointer to a DWORD that contains the number of bytes available + * at pSid. The CreateWellKnownSid function stores the number of + * bytes actually used at this location. + * @return If the function succeeds, the return value is nonzero. If the + * function fails, the return value is zero. For extended error + * information, call GetLastError. + */ + boolean CreateWellKnownSid(int wellKnownSidType, PSID domainSid, + PSID pSid, IntByReference cbSid); + + /** + * The InitializeSecurityDescriptor function initializes a new security descriptor. + * @param pSecurityDescriptor + * A pointer to a SECURITY_DESCRIPTOR structure that the function initializes. + * @param dwRevision + * The revision level to assign to the security descriptor. This parameter + * must be SECURITY_DESCRIPTOR_REVISION. + * @return If the function succeeds, the return value is nonzero. If the + * function fails, the return value is zero. For extended error + * information, call GetLastError. + */ + boolean InitializeSecurityDescriptor(SECURITY_DESCRIPTOR pSecurityDescriptor, int dwRevision); + + /** + * The GetSecurityDescriptorControl function retrieves a security descriptor control and revision information. + * @param pSecurityDescriptor + * A pointer to a SECURITY_DESCRIPTOR structure whose control and revision + * information the function retrieves. + * @param pControl + * A pointer to a SECURITY_DESCRIPTOR_CONTROL structure that receives the security descriptor's + * control information. + * @param lpdwRevision + * A pointer to a variable that receives the security descriptor's revision value. + * This value is always set, even when GetSecurityDescriptorControl returns an error. + * @return If the function succeeds, the return value is nonzero. If the + * function fails, the return value is zero. For extended error + * information, call GetLastError. + */ + boolean GetSecurityDescriptorControl(SECURITY_DESCRIPTOR pSecurityDescriptor, ShortByReference pControl, IntByReference lpdwRevision); + + /** + * The SetSecurityDescriptorControl function sets the control bits of a security descriptor. The function can set only the control + * bits that relate to automatic inheritance of ACEs. To set the other control bits of a security descriptor, use the functions, + * such as SetSecurityDescriptorDacl, for modifying the components of a security descriptor. + * @param pSecurityDescriptor + * A pointer to a SECURITY_DESCRIPTOR structure whose control and revision information are set. + * @param ControlBitsOfInterest + * A SECURITY_DESCRIPTOR_CONTROL mask that indicates the control bits to set. + * @param ControlBitsToSet + * SECURITY_DESCRIPTOR_CONTROL mask that indicates the new values for the control bits specified by the ControlBitsOfInterest mask. + * @return If the function succeeds, the return value is nonzero. If the + * function fails, the return value is zero. For extended error + * information, call GetLastError. + */ + boolean SetSecurityDescriptorControl(SECURITY_DESCRIPTOR pSecurityDescriptor, short ControlBitsOfInterest, short ControlBitsToSet); + + /** + * The GetSecurityDescriptorOwner function retrieves the owner information from a security descriptor. + * @param pSecurityDescriptor + * A pointer to a SECURITY_DESCRIPTOR structure whose owner information the function retrieves. + * @param pOwner + * A pointer to a pointer to a security identifier (SID) that identifies the owner when the function returns. + * If the security descriptor does not contain an owner, the function sets the pointer pointed to by pOwner + * to NULL and ignores the remaining output parameter, lpbOwnerDefaulted. If the security descriptor contains an owner, + * the function sets the pointer pointed to by pOwner to the address of the security descriptor's owner SID + * and provides a valid value for the variable pointed to by lpbOwnerDefaulted. + * @param lpbOwnerDefaulted + * A pointer to a flag that is set to the value of the SE_OWNER_DEFAULTED flag in the SECURITY_DESCRIPTOR_CONTROL + * structure when the function returns. If the value stored in the variable pointed to by the pOwner parameter is + * NULL, no value is set. + * @return If the function succeeds, the return value is nonzero. If the + * function fails, the return value is zero. For extended error + * information, call GetLastError. + */ + boolean GetSecurityDescriptorOwner(SECURITY_DESCRIPTOR pSecurityDescriptor, PSIDByReference pOwner, BOOLByReference lpbOwnerDefaulted); + + /** + * The SetSecurityDescriptorOwner function sets the owner information of an absolute-format security descriptor. It replaces + * any owner information already present in the security descriptor. + * @param pSecurityDescriptor + * A pointer to the SECURITY_DESCRIPTOR structure whose owner is set by this function. The function replaces any existing + * owner with the new owner. + * @param pOwner + * A pointer to a SID structure for the security descriptor's new primary owner. The SID structure is referenced by, not + * copied into, the security descriptor. If this parameter is NULL, the function clears the security descriptor's owner + * information. This marks the security descriptor as having no owner. + * @param bOwnerDefaulted + * Indicates whether the owner information is derived from a default mechanism. If this value is TRUE, it is default information. + * The function stores this value as the SE_OWNER_DEFAULTED flag in the SECURITY_DESCRIPTOR_CONTROL structure. If this parameter + * is zero, the SE_OWNER_DEFAULTED flag is cleared. + * @return If the function succeeds, the return value is nonzero. If the + * function fails, the return value is zero. For extended error + * information, call GetLastError. + */ + boolean SetSecurityDescriptorOwner(SECURITY_DESCRIPTOR pSecurityDescriptor, PSID pOwner, boolean bOwnerDefaulted); + + /** + * The GetSecurityDescriptorGroup function retrieves the primary group information from a security descriptor. + * @param pSecurityDescriptor + * A pointer to a SECURITY_DESCRIPTOR structure whose primary group information the function retrieves. + * @param pGroup + * A pointer to a pointer to a security identifier (SID) that identifies the primary group when the function + * returns. If the security descriptor does not contain a primary group, the function sets the pointer + * pointed to by pGroup to NULL and ignores the remaining output parameter, lpbGroupDefaulted. If the + * security descriptor contains a primary group, the function sets the pointer pointed to by pGroup to the + * address of the security descriptor's group SID and provides a valid value for the variable pointed to + * by lpbGroupDefaulted. + * @param lpbGroupDefaulted + * A pointer to a flag that is set to the value of the SE_GROUP_DEFAULTED flag in the + * SECURITY_DESCRIPTOR_CONTROL structure when the function returns. If the value stored in the variable + * pointed to by the pGroup parameter is NULL, no value is set. + * @return If the function succeeds, the return value is nonzero. If the + * function fails, the return value is zero. For extended error + * information, call GetLastError. + */ + boolean GetSecurityDescriptorGroup(SECURITY_DESCRIPTOR pSecurityDescriptor, PSIDByReference pGroup, BOOLByReference lpbGroupDefaulted); + + /** + * The SetSecurityDescriptorGroup function sets the primary group information of an absolute-format security descriptor, replacing + * any primary group information already present in the security descriptor. + * @param pSecurityDescriptor + * A pointer to the SECURITY_DESCRIPTOR structure whose primary group is set by this function. The function replaces + * any existing primary group with the new primary group. + * @param pGroup + * A pointer to a SID structure for the security descriptor's new primary group. The SID structure is referenced by, not copied + * into, the security descriptor. If this parameter is NULL, the function clears the security descriptor's primary group + * information. This marks the security descriptor as having no primary group. + * @param bGroupDefaulted + * Indicates whether the primary group information was derived from a default mechanism. If this value is TRUE, it is default + * information, and the function stores this value as the SE_GROUP_DEFAULTED flag in the SECURITY_DESCRIPTOR_CONTROL structure. + * If this parameter is zero, the SE_GROUP_DEFAULTED flag is cleared. + * @return If the function succeeds, the return value is nonzero. If the + * function fails, the return value is zero. For extended error + * information, call GetLastError. + */ + boolean SetSecurityDescriptorGroup(SECURITY_DESCRIPTOR pSecurityDescriptor, PSID pGroup, boolean bGroupDefaulted); - public static final int RRF_RT_ANY = 0x0000ffff; - public static final int RRF_RT_DWORD = 0x00000018; - public static final int RRF_RT_QWORD = 0x00000048; - public static final int RRF_RT_REG_BINARY = 0x00000008; - public static final int RRF_RT_REG_DWORD = 0x00000010; - public static final int RRF_RT_REG_EXPAND_SZ = 0x00000004; - public static final int RRF_RT_REG_MULTI_SZ = 0x00000020; - public static final int RRF_RT_REG_NONE = 0x00000001; - public static final int RRF_RT_REG_QWORD = 0x00000040; - public static final int RRF_RT_REG_SZ = 0x00000002; - - /** - * Retrieves the name of the user associated with the current thread. - * http://msdn.microsoft.com/en-us/library/ms724432(VS.85).aspx - * - * @param buffer - * Buffer to receive the user's logon name. - * @param len - * On input, the size of the buffer, on output the number of - * characters copied into the buffer, including the terminating - * null character. - * @return True if succeeded. - */ - public boolean GetUserNameW(char[] buffer, IntByReference len); - - /** - * Accepts the name of a system and anaccount as input and retrieves a - * security identifier (SID) for the account and the name of the domain on - * which the account was found. - * http://msdn.microsoft.com/en-us/library/aa379159(VS.85).aspx - * - * @param lpSystemName - * Specifies the name of the system. - * @param lpAccountName - * Specifies the account name. - * @param Sid - * Receives the SID structure that corresponds to the account - * name pointed to by the lpAccountName parameter. - * @param cbSid - * On input, this value specifies the size, in bytes, of the Sid - * buffer. If the function fails because the buffer is too small - * or if cbSid is zero, this variable receives the required - * buffer size. - * @param ReferencedDomainName - * Receives the name of the domain where the account name is - * found. - * @param cchReferencedDomainName - * On input, this value specifies the size, in TCHARs, of the - * ReferencedDomainName buffer. If the function fails because the - * buffer is too small, this variable receives the required - * buffer size, including the terminating null character. - * @param peUse - * SID_NAME_USE enumerated type that indicates the type of the - * account when the function returns. - * @return True if the function was successful, False otherwise. - */ - public boolean LookupAccountName(String lpSystemName, String lpAccountName, - PSID Sid, IntByReference cbSid, char[] ReferencedDomainName, - IntByReference cchReferencedDomainName, PointerByReference peUse); - - /** - * Retrieves the name of the account for this SID and the name of the first - * domain on which this SID is found. - * - * @param lpSystemName - * Specifies the target computer. - * @param Sid - * The SID to look up. - * @param lpName - * Buffer that receives a null-terminated string that contains - * the account name that corresponds to the lpSid parameter. - * @param cchName - * On input, specifies the size, in TCHARs, of the lpName buffer. - * If the function fails because the buffer is too small or if - * cchName is zero, cchName receives the required buffer size, - * including the terminating null character. - * @param ReferencedDomainName - * Pointer to a buffer that receives a null-terminated string - * that contains the name of the domain where the account name - * was found. - * @param cchReferencedDomainName - * On input, specifies the size, in TCHARs, of the - * lpReferencedDomainName buffer. If the function fails because - * the buffer is too small or if cchReferencedDomainName is zero, - * cchReferencedDomainName receives the required buffer size, - * including the terminating null character. - * @param peUse - * Pointer to a variable that receives a SID_NAME_USE value that - * indicates the type of the account. - * @return If the function succeeds, the function returns nonzero. If the - * function fails, it returns zero. To get extended error - * information, call GetLastError. - */ - public boolean LookupAccountSid(String lpSystemName, PSID Sid, - char[] lpName, IntByReference cchName, char[] ReferencedDomainName, - IntByReference cchReferencedDomainName, PointerByReference peUse); - - /** - * Convert a security identifier (SID) to a string format suitable for - * display, storage, or transmission. - * http://msdn.microsoft.com/en-us/library/aa376399(VS.85).aspx - * - * @param Sid - * The SID structure to be converted. - * @param StringSid - * Pointer to a variable that receives a pointer to a - * null-terminated SID string. To free the returned buffer, call - * the LocalFree function. - * @return True if the function was successful, False otherwise. - */ - public boolean ConvertSidToStringSid(PSID Sid, PointerByReference StringSid); - - /** - * Convert a string-format security identifier (SID) into a valid, - * functional SID. - * http://msdn.microsoft.com/en-us/library/aa376402(VS.85).aspx - * - * @param StringSid - * The string-format SID to convert. - * @param Sid - * Receives a pointer to the converted SID. - * @return True if the function was successful, False otherwise. - */ - public boolean ConvertStringSidToSid(String StringSid, PSIDByReference Sid); - - /** - * Returns the length, in bytes, of a valid security identifier (SID). - * http://msdn.microsoft.com/en-us/library/aa446642(VS.85).aspx - * - * @param pSid - * A pointer to the SID structure whose length is returned. - * @return Length of the SID. - */ - public int GetLengthSid(PSID pSid); - - /** - * The IsValidSid function validates a security identifier (SID) by - * verifying that the revision number is within a known range, and that the - * number of subauthorities is less than the maximum. - * - * @param pSid - * Pointer to the SID structure to validate. This parameter - * cannot be NULL. - * @return If the SID structure is valid, the return value is nonzero. If - * the SID structure is not valid, the return value is zero. There - * is no extended error information for this function; do not call - * GetLastError. - */ - public boolean IsValidSid(PSID pSid); - - /** - * Compares a SID to a well known SID and returns TRUE if they match. - * - * @param pSid - * SID to test. - * @param wellKnownSidType - * Member of the WELL_KNOWN_SID_TYPE enumeration to compare with - * the SID at pSid. - * @return True if the SID is of a given well known type, false otherwise. - */ - public boolean IsWellKnownSid(PSID pSid, int wellKnownSidType); - - /** - * The CreateWellKnownSid function creates a SID for predefined aliases. - * - * @param wellKnownSidType - * Member of the WELL_KNOWN_SID_TYPE enumeration that specifies - * what the SID will identify. - * @param domainSid - * Pointer to a SID that identifies the domain control to use - * when creating the SID. Pass NULL to use the local computer. - * @param pSid - * Pointer to memory where CreateWellKnownSid will store the new - * SID. - * @param cbSid - * Pointer to a DWORD that contains the number of bytes available - * at pSid. The CreateWellKnownSid function stores the number of - * bytes actually used at this location. - * @return If the function succeeds, the return value is nonzero. If the - * function fails, the return value is zero. For extended error - * information, call GetLastError. - */ - public boolean CreateWellKnownSid(int wellKnownSidType, PSID domainSid, - PSID pSid, IntByReference cbSid); - - /** - * The LogonUser function attempts to log a user on to the local computer. - * The local computer is the computer from which LogonUser was called. You - * cannot use LogonUser to log on to a remote computer. You specify the user - * with a user name and domain, and authenticate the user with a plaintext - * password. If the function succeeds, you receive a handle to a token that - * represents the logged-on user. You can then use this token handle to - * impersonate the specified user or, in most cases, to create a process - * that runs in the context of the specified user. - * - * @param lpszUsername - * A pointer to a null-terminated string that specifies the name - * of the user. This is the name of the user account to log on - * to. If you use the user principal name (UPN) format, - * user@DNS_domain_name, the lpszDomain parameter must be NULL. - * @param lpszDomain - * A pointer to a null-terminated string that specifies the name - * of the domain or server whose account database contains the - * lpszUsername account. If this parameter is NULL, the user name - * must be specified in UPN format. If this parameter is ".", the - * function validates the account using only the local account - * database. - * @param lpszPassword - * A pointer to a null-terminated string that specifies the - * plaintext password for the user account specified by - * lpszUsername. - * @param logonType - * The type of logon operation to perform. - * @param logonProvider - * Specifies the logon provider. - * @param phToken - * A pointer to a handle variable that receives a handle to a - * token that represents the specified user. - * @return If the function succeeds, the function returns nonzero. If the - * function fails, it returns zero. To get extended error - * information, call GetLastError. - */ - public boolean LogonUser(String lpszUsername, String lpszDomain, - String lpszPassword, int logonType, int logonProvider, - HANDLEByReference phToken); - - /** - * The OpenThreadToken function opens the access token associated with a - * thread. - * - * @param ThreadHandle - * Handle to the thread whose access token is opened. - * @param DesiredAccess - * Specifies an access mask that specifies the requested types of - * access to the access token. These requested access types are - * reconciled against the token's discretionary access control - * list (DACL) to determine which accesses are granted or denied. - * @param OpenAsSelf - * Indicates whether the access check is to be made against the - * security context of the thread calling the OpenThreadToken - * function or against the security context of the process for - * the calling thread. - * @param TokenHandle - * Pointer to a variable that receives the handle to the newly - * opened access token. - * @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. - */ - public boolean OpenThreadToken(HANDLE ThreadHandle, int DesiredAccess, - boolean OpenAsSelf, HANDLEByReference TokenHandle); - - /** - * The SetThreadToken function assigns an impersonation token to a thread. - * The function can also cause a thread to stop using an impersonation token. - * @param ThreadHandle [in, optional] - * A pointer to a handle to the thread to which the function - * assigns the impersonation token. If ThreadHandle is NULL, the - * function assigns the impersonation token to the calling thread. - * @param TokenHandle [in, optional] - * A handle to the impersonation token to assign to the thread. - * This handle must have been opened with TOKEN_IMPERSONATE access - * rights. For more information, see Access Rights for Access-Token - * Objects. If Token is NULL, the function causes the - * thread to stop using an impersonation token. - * @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. - */ - public boolean SetThreadToken(HANDLEByReference ThreadHandle, HANDLE TokenHandle); - - /** - * The OpenProcessToken function opens the access token associated with a - * process. - * - * @param ProcessHandle - * Handle to the process whose access token is opened. The - * process must have the PROCESS_QUERY_INFORMATION access - * permission. - * @param DesiredAccess - * Specifies an access mask that specifies the requested types of - * access to the access token. These requested access types are - * compared with the discretionary access control list (DACL) of - * the token to determine which accesses are granted or denied. - * @param TokenHandle - * Pointer to a handle that identifies the newly opened access - * token when the function returns. - * @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. - */ - public boolean OpenProcessToken(HANDLE ProcessHandle, int DesiredAccess, - HANDLEByReference TokenHandle); - - /** - * The DuplicateToken function creates a new access token that duplicates - * one already in existence. - * - * @param ExistingTokenHandle - * Handle to an access token opened with TOKEN_DUPLICATE access. - * @param ImpersonationLevel - * Specifies a SECURITY_IMPERSONATION_LEVEL enumerated type that - * supplies the impersonation level of the new token. - * @param DuplicateTokenHandle - * Pointer to a variable that receives a handle to the duplicate - * token. This handle has TOKEN_IMPERSONATE and TOKEN_QUERY - * access to the new token. - * @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. - */ - public boolean DuplicateToken(HANDLE ExistingTokenHandle, - int ImpersonationLevel, HANDLEByReference DuplicateTokenHandle); - - /** - * The DuplicateTokenEx function creates a new access token that duplicates - * an existing token. This function can create either a primary token or an - * impersonation token. - * - * @param hExistingToken - * A handle to an access token opened with TOKEN_DUPLICATE - * access. - * @param dwDesiredAccess - * Specifies the requested access rights for the new token. - * @param lpTokenAttributes - * A pointer to a SECURITY_ATTRIBUTES structure that specifies a - * security descriptor for the new token and determines whether - * child processes can inherit the token. - * @param ImpersonationLevel - * Specifies a value from the SECURITY_IMPERSONATION_LEVEL - * enumeration that indicates the impersonation level of the new - * token. - * @param TokenType - * Specifies one of the following values from the TOKEN_TYPE - * enumeration. - * @param phNewToken - * A pointer to a HANDLE variable that receives the new token. - * @return If the function succeeds, the function returns a nonzero value. - * If the function fails, it returns zero. To get extended error - * information, call GetLastError. - */ - public boolean DuplicateTokenEx(HANDLE hExistingToken, int dwDesiredAccess, - WinBase.SECURITY_ATTRIBUTES lpTokenAttributes, - int ImpersonationLevel, int TokenType, HANDLEByReference phNewToken); - - /** - * Retrieves a specified type of information about an access token. The - * calling process must have appropriate access rights to obtain the - * information. - * - * @param tokenHandle - * Handle to an access token from which information is retrieved. - * If TokenInformationClass specifies TokenSource, the handle - * must have TOKEN_QUERY_SOURCE access. For all other - * TokenInformationClass values, the handle must have TOKEN_QUERY - * access. - * @param tokenInformationClass - * Specifies a value from the TOKEN_INFORMATION_CLASS enumerated - * type to identify the type of information the function - * retrieves. - * @param tokenInformation - * Pointer to a buffer the function fills with the requested - * information. The structure put into this buffer depends upon - * the type of information specified by the TokenInformationClass - * parameter. - * @param tokenInformationLength - * Specifies the size, in bytes, of the buffer pointed to by the - * TokenInformation parameter. If TokenInformation is NULL, this - * parameter must be zero. - * @param returnLength - * Pointer to a variable that receives the number of bytes needed - * for the buffer pointed to by the TokenInformation parameter. - * If this value is larger than the value specified in the - * TokenInformationLength parameter, the function fails and - * stores no data in the buffer. - * @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. - */ - public boolean GetTokenInformation(HANDLE tokenHandle, - int tokenInformationClass, Structure tokenInformation, - int tokenInformationLength, IntByReference returnLength); - - /** - * The ImpersonateLoggedOnUser function lets the calling thread impersonate - * the security context of a logged-on user. The user is represented by a - * token handle. - * - * @param hToken - * Handle to a primary or impersonation access token that - * represents a logged-on user. This can be a token handle - * returned by a call to LogonUser, CreateRestrictedToken, - * DuplicateToken, DuplicateTokenEx, OpenProcessToken, or - * OpenThreadToken functions. If hToken is a primary token, it - * must have TOKEN_QUERY and TOKEN_DUPLICATE access. If hToken is - * an impersonation token, it must have TOKEN_QUERY and - * TOKEN_IMPERSONATE access. - * @return If the function succeeds, the return value is nonzero. - */ - public boolean ImpersonateLoggedOnUser(HANDLE hToken); - - /** - * The ImpersonateSelf function obtains an access token that impersonates - * the security context of the calling process. The token is assigned to the - * calling thread. - * - * @param ImpersonationLevel - * Specifies a SECURITY_IMPERSONATION_LEVEL enumerated type that - * supplies the impersonation level of the new token. - * @return If the function succeeds, the return value is nonzero. - */ - public boolean ImpersonateSelf(int ImpersonationLevel); - - /** - * The RevertToSelf function terminates the impersonation of a client - * application. - * - * @return If the function succeeds, the return value is nonzero. - */ - public boolean RevertToSelf(); - - /** - * The RegOpenKeyEx function opens the specified registry key. Note that key - * names are not case sensitive. - * - * @param hKey - * Handle to an open key. - * @param lpSubKey - * Pointer to a null-terminated string containing the name of the - * subkey to open. - * @param ulOptions - * Reserved; must be zero. - * @param samDesired - * Access mask that specifies the desired access rights to the - * key. The function fails if the security descriptor of the key - * does not permit the requested access for the calling process. - * @param phkResult - * Pointer to a variable that receives a handle to the opened - * key. If the key is not one of the predefined registry keys, - * call the RegCloseKey function after you have finished using - * the handle. - * @return If the function succeeds, the return value is ERROR_SUCCESS. If - * the function fails, the return value is a nonzero error code - * defined in Winerror.h. - */ - public int RegOpenKeyEx(HKEY hKey, String lpSubKey, int ulOptions, - int samDesired, HKEYByReference phkResult); - - /** - * The RegQueryValueEx function retrieves the type and data for a specified - * value name associated with an open registry key. - * - * @param hKey - * Handle to an open key. The key must have been opened with the - * KEY_QUERY_VALUE access right. - * @param lpValueName - * Pointer to a null-terminated string containing the name of the - * value to query. If lpValueName is NULL or an empty string, "", - * the function retrieves the type and data for the key's unnamed - * or default value, if any. - * @param lpReserved - * Reserved; must be NULL. - * @param lpType - * Pointer to a variable that receives a code indicating the type - * of data stored in the specified value. - * @param lpData - * Pointer to a buffer that receives the value's data. This - * parameter can be NULL if the data is not required. If the data - * is a string, the function checks for a terminating null - * character. If one is not found, the string is stored with a - * null terminator if the buffer is large enough to accommodate - * the extra character. Otherwise, the string is stored as is. - * @param lpcbData - * Pointer to a variable that specifies the size of the buffer - * pointed to by the lpData parameter, in bytes. When the - * function returns, this variable contains the size of the data - * copied to lpData. The lpcbData parameter can be NULL only if - * lpData is NULL. If the data has the REG_SZ, REG_MULTI_SZ or - * REG_EXPAND_SZ type, this size includes any terminating null - * character or characters. If the buffer specified by lpData - * parameter is not large enough to hold the data, the function - * returns ERROR_MORE_DATA and stores the required buffer size in - * the variable pointed to by lpcbData. In this case, the - * contents of the lpData buffer are undefined. If lpData is - * NULL, and lpcbData is non-NULL, the function returns - * ERROR_SUCCESS and stores the size of the data, in bytes, in - * the variable pointed to by lpcbData. This enables an - * application to determine the best way to allocate a buffer for - * the value's data. - * @return If the function succeeds, the return value is ERROR_SUCCESS. If - * the function fails, the return value is a nonzero error code - * defined in Winerror.h. - */ - public int RegQueryValueEx(HKEY hKey, String lpValueName, int lpReserved, + /** + * The GetSecurityDescriptorDacl function retrieves a pointer to the discretionary access control list (DACL) in + * a specified security descriptor. + * @param pSecurityDescriptor + * A pointer to the SECURITY_DESCRIPTOR structure that contains the DACL. The function retrieves a pointer to it. + * @param bDaclPresent + * A pointer to a value that indicates the presence of a DACL in the specified security descriptor. If + * lpbDaclPresent is TRUE, the security descriptor contains a DACL, and the remaining output parameters in this + * function receive valid values. If lpbDaclPresent is FALSE, the security descriptor does not contain a DACL, + * and the remaining output parameters do not receive valid values. A value of TRUE for lpbDaclPresent does not + * mean that pDacl is not NULL. That is, lpbDaclPresent can be TRUE while pDacl is NULL, meaning that a NULL + * DACL is in effect. A NULL DACL implicitly allows all access to an object and is not the same as an empty DACL. + * An empty DACL permits no access to an object. For information about creating a proper DACL, see Creating a DACL. + * @param pDacl + * A pointer to a pointer to an access control list (ACL). If a DACL exists, the function sets the pointer pointed + * to by pDacl to the address of the security descriptor's DACL. If a DACL does not exist, no value is stored. + * If the function stores a NULL value in the pointer pointed to by pDacl, the security descriptor has a NULL DACL. + * A NULL DACL implicitly allows all access to an object. + * If an application expects a non-NULL DACL but encounters a NULL DACL, the application should fail securely and + * not allow access. + * @param bDaclDefaulted + * A pointer to a flag set to the value of the SE_DACL_DEFAULTED flag in the SECURITY_DESCRIPTOR_CONTROL structure + * if a DACL exists for the security descriptor. If this flag is TRUE, the DACL was retrieved by a default mechanism; + * if FALSE, the DACL was explicitly specified by a user. + * @return If the function succeeds, the return value is nonzero. If the + * function fails, the return value is zero. For extended error + * information, call GetLastError. + */ + boolean GetSecurityDescriptorDacl(SECURITY_DESCRIPTOR pSecurityDescriptor, BOOLByReference bDaclPresent, PACLByReference pDacl, BOOLByReference bDaclDefaulted); + + /** + * The SetSecurityDescriptorDacl function sets information in a discretionary access control list (DACL). + * If a DACL is already present in the security descriptor, the DACL is replaced. + * @param pSecurityDescriptor + * A pointer to the SECURITY_DESCRIPTOR structure to which the function adds the DACL. This + * security descriptor must be in absolute format, meaning that its members must be pointers + * to other structures, rather than offsets to contiguous data. + * @param bDaclPresent + * A flag that indicates the presence of a DACL in the security descriptor. If this parameter + * is TRUE, the function sets the SE_DACL_PRESENT flag in the SECURITY_DESCRIPTOR_CONTROL + * structure and uses the values in the pDacl and bDaclDefaulted parameters. If this parameter + * is FALSE, the function clears the SE_DACL_PRESENT flag, and pDacl and bDaclDefaulted are ignored. + * @param pDacl + * A pointer to an ACL structure that specifies the DACL for the security descriptor. If this + * parameter is NULL, a NULL DACL is assigned to the security descriptor, which allows all access + * to the object. The DACL is referenced by, not copied into, the security descriptor. + * @param bDaclDefaulted + * A flag that indicates the source of the DACL. If this flag is TRUE, the DACL has been retrieved + * by some default mechanism. If FALSE, the DACL has been explicitly specified by a user. The function + * stores this value in the SE_DACL_DEFAULTED flag of the SECURITY_DESCRIPTOR_CONTROL structure. If + * this parameter is not specified, the SE_DACL_DEFAULTED flag is cleared. + * @return If the function succeeds, the return value is nonzero. If the + * function fails, the return value is zero. For extended error + * information, call GetLastError. + */ + boolean SetSecurityDescriptorDacl(SECURITY_DESCRIPTOR pSecurityDescriptor, boolean bDaclPresent, ACL pDacl, boolean bDaclDefaulted); + + /** + * The InitializeAcl function initializes a new ACL structure. + * @param pAcl + * A pointer to an ACL structure to be initialized by this function. + * Allocate memory for pAcl before calling this function. + * @param nAclLength + * The length, in bytes, of the buffer pointed to by the pAcl parameter. This value + * must be large enough to contain the ACL header and all of the access control + * entries (ACEs) to be stored in the ACL. In addition, this value must be + * DWORD-aligned. For more information about calculating the size of an ACL, + * see Remarks. + * @param dwAclRevision + * The revision level of the ACL structure being created. This value can be ACL_REVISION + * or ACL_REVISION_DS. Use ACL_REVISION_DS if the access control list (ACL) supports + * object-specific ACEs. + * @return If the function succeeds, the return value is nonzero. If the + * function fails, the return value is zero. For extended error + * information, call GetLastError. + */ + boolean InitializeAcl(ACL pAcl, int nAclLength, int dwAclRevision); + + /** + * The AddAce function adds one or more access control entries (ACEs) to a specified access control list (ACL). + * @param pAcl + * A pointer to an ACL. This function adds an ACE to this ACL. + * @param dwAceRevision + * Specifies the revision level of the ACL being modified. This value can be ACL_REVISION or + * ACL_REVISION_DS. Use ACL_REVISION_DS if the ACL contains object-specific ACEs. This value + * must be compatible with the AceType field of all ACEs in pAceList. Otherwise, the function + * will fail and set the last error to ERROR_INVALID_PARAMETER. + * @param dwStartingAceIndex + * Specifies the position in the ACL's list of ACEs at which to add new ACEs. A value of zero + * inserts the ACEs at the beginning of the list. A value of MAXDWORD appends the ACEs to the end + * of the list. + * @param pAceList + * A pointer to a list of one or more ACEs to be added to the specified ACL. The ACEs in the list + * must be stored contiguously. + * @param nAceListLength + * Specifies the size, in bytes, of the input buffer pointed to by the pAceList parameter. + * @return If the function succeeds, the return value is nonzero. If the + * function fails, the return value is zero. For extended error + * information, call GetLastError. + */ + boolean AddAce(ACL pAcl, int dwAceRevision, int dwStartingAceIndex, Pointer pAceList, int nAceListLength); + + /** + * The AddAce function adds one or more access control entries (ACEs) to a specified access control list (ACL). + * @param pAcl + * A pointer to an ACL. This function adds an access-allowed ACE to the end of this ACL. + * The ACE is in the form of an ACCESS_ALLOWED_ACE structure. + * @param dwAceRevision + * Specifies the revision level of the ACL being modified. This value can be ACL_REVISION or + * ACL_REVISION_DS. Use ACL_REVISION_DS if the ACL contains object-specific ACEs. + * @param AccessMask + * Specifies the mask of access rights to be granted to the specified SID. + * @param pSid + * A pointer to the SID representing a user, group, or logon account being granted access. + * @return If the function succeeds, the return value is nonzero. If the + * function fails, the return value is zero. For extended error + * information, call GetLastError. + */ + boolean AddAccessAllowedAce(ACL pAcl, int dwAceRevision, int AccessMask, PSID pSid); + + /** + * The AddAce function adds one or more access control entries (ACEs) to a specified access control list (ACL). + * @param pAcl + * A pointer to an ACL. This function adds an access-allowed ACE to the end of this ACL. + * The ACE is in the form of an ACCESS_ALLOWED_ACE structure. + * @param dwAceRevision + * Specifies the revision level of the ACL being modified. This value can be ACL_REVISION or + * ACL_REVISION_DS. Use ACL_REVISION_DS if the ACL contains object-specific ACEs. + * @param AceFlags + * A set of bit flags that control ACE inheritance. The function sets these flags in the AceFlags + * member of the ACE_HEADER structure of the new ACE. This parameter can be a combination + * of the following values: CONTAINER_INHERIT_ACE, INHERIT_ONLY_ACE, INHERITED_ACE, + * NO_PROPAGATE_INHERIT_ACE, and OBJECT_INHERIT_ACE + * @param AccessMask + * Specifies the mask of access rights to be granted to the specified SID. + * @param pSid + * A pointer to the SID representing a user, group, or logon account being granted access. + * @return If the function succeeds, the return value is nonzero. If the + * function fails, the return value is zero. For extended error + * information, call GetLastError. + */ + boolean AddAccessAllowedAceEx(ACL pAcl, int dwAceRevision, int AceFlags, int AccessMask, PSID pSid); + + /** + * The GetAce function obtains a pointer to an access control entry (ACE) in an access + * control list (ACL). + * @param pAcl + * A pointer to an ACL that contains the ACE to be retrieved. + * @param dwAceIndex + * The index of the ACE to be retrieved. A value of zero corresponds to the first ACE in + * the ACL, a value of one to the second ACE, and so on. + * @param pAce + * A pointer to a pointer that the function sets to the address of the ACE. + * @return If the function succeeds, the return value is nonzero. If the + * function fails, the return value is zero. For extended error + * information, call GetLastError. + */ + boolean GetAce(ACL pAcl, int dwAceIndex, PointerByReference pAce); + + /** + * The LogonUser function attempts to log a user on to the local computer. + * The local computer is the computer from which LogonUser was called. You + * cannot use LogonUser to log on to a remote computer. You specify the user + * with a user name and domain, and authenticate the user with a plaintext + * password. If the function succeeds, you receive a handle to a token that + * represents the logged-on user. You can then use this token handle to + * impersonate the specified user or, in most cases, to create a process + * that runs in the context of the specified user. + * + * @param lpszUsername + * A pointer to a null-terminated string that specifies the name + * of the user. This is the name of the user account to log on + * to. If you use the user principal name (UPN) format, + * user@DNS_domain_name, the lpszDomain parameter must be NULL. + * @param lpszDomain + * A pointer to a null-terminated string that specifies the name + * of the domain or server whose account database contains the + * lpszUsername account. If this parameter is NULL, the user name + * must be specified in UPN format. If this parameter is ".", the + * function validates the account using only the local account + * database. + * @param lpszPassword + * A pointer to a null-terminated string that specifies the + * plaintext password for the user account specified by + * lpszUsername. + * @param logonType + * The type of logon operation to perform. + * @param logonProvider + * Specifies the logon provider. + * @param phToken + * A pointer to a handle variable that receives a handle to a + * token that represents the specified user. + * @return If the function succeeds, the function returns nonzero. If the + * function fails, it returns zero. To get extended error + * information, call GetLastError. + */ + boolean LogonUser(String lpszUsername, String lpszDomain, + String lpszPassword, int logonType, int logonProvider, + HANDLEByReference phToken); + + /** + * The OpenThreadToken function opens the access token associated with a + * thread. + * + * @param ThreadHandle + * Handle to the thread whose access token is opened. + * @param DesiredAccess + * Specifies an access mask that specifies the requested types of + * access to the access token. These requested access types are + * reconciled against the token's discretionary access control + * list (DACL) to determine which accesses are granted or denied. + * @param OpenAsSelf + * Indicates whether the access check is to be made against the + * security context of the thread calling the OpenThreadToken + * function or against the security context of the process for + * the calling thread. + * @param TokenHandle + * Pointer to a variable that receives the handle to the newly + * opened access token. + * @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. + */ + boolean OpenThreadToken(HANDLE ThreadHandle, int DesiredAccess, + boolean OpenAsSelf, HANDLEByReference TokenHandle); + + /** + * The SetThreadToken function assigns an impersonation token to a thread. + * The function can also cause a thread to stop using an impersonation token. + * @param ThreadHandle [in, optional] + * A pointer to a handle to the thread to which the function + * assigns the impersonation token. If ThreadHandle is NULL, the + * function assigns the impersonation token to the calling thread. + * @param TokenHandle [in, optional] + * A handle to the impersonation token to assign to the thread. + * This handle must have been opened with TOKEN_IMPERSONATE access + * rights. For more information, see Access Rights for Access-Token + * Objects. If Token is NULL, the function causes the + * thread to stop using an impersonation token. + * @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. + */ + boolean SetThreadToken(HANDLEByReference ThreadHandle, HANDLE TokenHandle); + + /** + * The OpenProcessToken function opens the access token associated with a + * process. + * + * @param ProcessHandle + * Handle to the process whose access token is opened. The + * process must have the PROCESS_QUERY_INFORMATION access + * permission. + * @param DesiredAccess + * Specifies an access mask that specifies the requested types of + * access to the access token. These requested access types are + * compared with the discretionary access control list (DACL) of + * the token to determine which accesses are granted or denied. + * @param TokenHandle + * Pointer to a handle that identifies the newly opened access + * token when the function returns. + * @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. + */ + boolean OpenProcessToken(HANDLE ProcessHandle, int DesiredAccess, + HANDLEByReference TokenHandle); + + /** + * The DuplicateToken function creates a new access token that duplicates + * one already in existence. + * + * @param ExistingTokenHandle + * Handle to an access token opened with TOKEN_DUPLICATE access. + * @param ImpersonationLevel + * Specifies a SECURITY_IMPERSONATION_LEVEL enumerated type that + * supplies the impersonation level of the new token. + * @param DuplicateTokenHandle + * Pointer to a variable that receives a handle to the duplicate + * token. This handle has TOKEN_IMPERSONATE and TOKEN_QUERY + * access to the new token. + * @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. + */ + boolean DuplicateToken(HANDLE ExistingTokenHandle, + int ImpersonationLevel, HANDLEByReference DuplicateTokenHandle); + + /** + * The DuplicateTokenEx function creates a new access token that duplicates + * an existing token. This function can create either a primary token or an + * impersonation token. + * + * @param hExistingToken + * A handle to an access token opened with TOKEN_DUPLICATE + * access. + * @param dwDesiredAccess + * Specifies the requested access rights for the new token. + * @param lpTokenAttributes + * A pointer to a SECURITY_ATTRIBUTES structure that specifies a + * security descriptor for the new token and determines whether + * child processes can inherit the token. + * @param ImpersonationLevel + * Specifies a value from the SECURITY_IMPERSONATION_LEVEL + * enumeration that indicates the impersonation level of the new + * token. + * @param TokenType + * Specifies one of the following values from the TOKEN_TYPE + * enumeration. + * @param phNewToken + * A pointer to a HANDLE variable that receives the new token. + * @return If the function succeeds, the function returns a nonzero value. + * If the function fails, it returns zero. To get extended error + * information, call GetLastError. + */ + boolean DuplicateTokenEx(HANDLE hExistingToken, int dwDesiredAccess, + WinBase.SECURITY_ATTRIBUTES lpTokenAttributes, + int ImpersonationLevel, int TokenType, HANDLEByReference phNewToken); + + /** + * Retrieves a specified type of information about an access token. The + * calling process must have appropriate access rights to obtain the + * information. + * + * @param tokenHandle + * Handle to an access token from which information is retrieved. + * If TokenInformationClass specifies TokenSource, the handle + * must have TOKEN_QUERY_SOURCE access. For all other + * TokenInformationClass values, the handle must have TOKEN_QUERY + * access. + * @param tokenInformationClass + * Specifies a value from the TOKEN_INFORMATION_CLASS enumerated + * type to identify the type of information the function + * retrieves. + * @param tokenInformation + * Pointer to a buffer the function fills with the requested + * information. The structure put into this buffer depends upon + * the type of information specified by the TokenInformationClass + * parameter. + * @param tokenInformationLength + * Specifies the size, in bytes, of the buffer pointed to by the + * TokenInformation parameter. If TokenInformation is NULL, this + * parameter must be zero. + * @param returnLength + * Pointer to a variable that receives the number of bytes needed + * for the buffer pointed to by the TokenInformation parameter. + * If this value is larger than the value specified in the + * TokenInformationLength parameter, the function fails and + * stores no data in the buffer. + * @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. + */ + boolean GetTokenInformation(HANDLE tokenHandle, + int tokenInformationClass, Structure tokenInformation, + int tokenInformationLength, IntByReference returnLength); + + /** + * The ImpersonateLoggedOnUser function lets the calling thread impersonate + * the security context of a logged-on user. The user is represented by a + * token handle. + * + * @param hToken + * Handle to a primary or impersonation access token that + * represents a logged-on user. This can be a token handle + * returned by a call to LogonUser, CreateRestrictedToken, + * DuplicateToken, DuplicateTokenEx, OpenProcessToken, or + * OpenThreadToken functions. If hToken is a primary token, it + * must have TOKEN_QUERY and TOKEN_DUPLICATE access. If hToken is + * an impersonation token, it must have TOKEN_QUERY and + * TOKEN_IMPERSONATE access. + * @return If the function succeeds, the return value is nonzero. + */ + boolean ImpersonateLoggedOnUser(HANDLE hToken); + + /** + * The ImpersonateSelf function obtains an access token that impersonates + * the security context of the calling process. The token is assigned to the + * calling thread. + * + * @param ImpersonationLevel + * Specifies a SECURITY_IMPERSONATION_LEVEL enumerated type that + * supplies the impersonation level of the new token. + * @return If the function succeeds, the return value is nonzero. + */ + boolean ImpersonateSelf(int ImpersonationLevel); + + /** + * The RevertToSelf function terminates the impersonation of a client + * application. + * + * @return If the function succeeds, the return value is nonzero. + */ + boolean RevertToSelf(); + + /** + * The RegOpenKeyEx function opens the specified registry key. Note that key + * names are not case sensitive. + * + * @param hKey + * Handle to an open key. + * @param lpSubKey + * Pointer to a null-terminated string containing the name of the + * subkey to open. + * @param ulOptions + * Reserved; must be zero. + * @param samDesired + * Access mask that specifies the desired access rights to the + * key. The function fails if the security descriptor of the key + * does not permit the requested access for the calling process. + * @param phkResult + * Pointer to a variable that receives a handle to the opened + * key. If the key is not one of the predefined registry keys, + * call the RegCloseKey function after you have finished using + * the handle. + * @return If the function succeeds, the return value is ERROR_SUCCESS. If + * the function fails, the return value is a nonzero error code + * defined in Winerror.h. + */ + int RegOpenKeyEx(HKEY hKey, String lpSubKey, int ulOptions, + int samDesired, HKEYByReference phkResult); + + /** + * The RegQueryValueEx function retrieves the type and data for a specified + * value name associated with an open registry key. + * + * @param hKey + * Handle to an open key. The key must have been opened with the + * KEY_QUERY_VALUE access right. + * @param lpValueName + * Pointer to a null-terminated string containing the name of the + * value to query. If lpValueName is NULL or an empty string, "", + * the function retrieves the type and data for the key's unnamed + * or default value, if any. + * @param lpReserved + * Reserved; must be NULL. + * @param lpType + * Pointer to a variable that receives a code indicating the type + * of data stored in the specified value. + * @param lpData + * Pointer to a buffer that receives the value's data. This + * parameter can be NULL if the data is not required. If the data + * is a string, the function checks for a terminating null + * character. If one is not found, the string is stored with a + * null terminator if the buffer is large enough to accommodate + * the extra character. Otherwise, the string is stored as is. + * @param lpcbData + * Pointer to a variable that specifies the size of the buffer + * pointed to by the lpData parameter, in bytes. When the + * function returns, this variable contains the size of the data + * copied to lpData. The lpcbData parameter can be NULL only if + * lpData is NULL. If the data has the REG_SZ, REG_MULTI_SZ or + * REG_EXPAND_SZ type, this size includes any terminating null + * character or characters. If the buffer specified by lpData + * parameter is not large enough to hold the data, the function + * returns ERROR_MORE_DATA and stores the required buffer size in + * the variable pointed to by lpcbData. In this case, the + * contents of the lpData buffer are undefined. If lpData is + * NULL, and lpcbData is non-NULL, the function returns + * ERROR_SUCCESS and stores the size of the data, in bytes, in + * the variable pointed to by lpcbData. This enables an + * application to determine the best way to allocate a buffer for + * the value's data. + * @return If the function succeeds, the return value is ERROR_SUCCESS. If + * the function fails, the return value is a nonzero error code + * defined in Winerror.h. + */ + int RegQueryValueEx(HKEY hKey, String lpValueName, int lpReserved, IntByReference lpType, char[] lpData, IntByReference lpcbData); - public int RegQueryValueEx(HKEY hKey, String lpValueName, int lpReserved, + int RegQueryValueEx(HKEY hKey, String lpValueName, int lpReserved, IntByReference lpType, byte[] lpData, IntByReference lpcbData); - public int RegQueryValueEx(HKEY hKey, String lpValueName, int lpReserved, + int RegQueryValueEx(HKEY hKey, String lpValueName, int lpReserved, IntByReference lpType, IntByReference lpData, IntByReference lpcbData); - public int RegQueryValueEx(HKEY hKey, String lpValueName, int lpReserved, + int RegQueryValueEx(HKEY hKey, String lpValueName, int lpReserved, IntByReference lpType, LongByReference lpData, IntByReference lpcbData); - public int RegQueryValueEx(HKEY hKey, String lpValueName, int lpReserved, + int RegQueryValueEx(HKEY hKey, String lpValueName, int lpReserved, IntByReference lpType, Pointer lpData, IntByReference lpcbData); - /** - * The RegCloseKey function releases a handle to the specified registry key. - * - * @param hKey - * Handle to the open key to be closed. The handle must have been - * opened by the RegCreateKeyEx, RegOpenKeyEx, or - * RegConnectRegistry function. - * @return If the function succeeds, the return value is ERROR_SUCCESS. If - * the function fails, the return value is a nonzero error code - * defined in Winerror.h. - */ - public int RegCloseKey(HKEY hKey); - - /** - * The RegDeleteValue function removes a named value from the specified - * registry key. Note that value names are not case sensitive. - * - * @param hKey - * Handle to an open key. The key must have been opened with the - * KEY_SET_VALUE access right. - * @param lpValueName - * Pointer to a null-terminated string that names the value to - * remove. If this parameter is NULL or an empty string, the - * value set by the RegSetValue function is removed. - * @return If the function succeeds, the return value is ERROR_SUCCESS. If - * the function fails, the return value is a nonzero error code - * defined in Winerror.h. - */ - public int RegDeleteValue(HKEY hKey, String lpValueName); - - /** - * The RegSetValueEx function sets the data and type of a specified value - * under a registry key. - * - * @param hKey - * Handle to an open key. The key must have been opened with the - * KEY_SET_VALUE access right. - * @param lpValueName - * Pointer to a string containing the name of the value to set. - * If a value with this name is not already present in the key, - * the function adds it to the key. If lpValueName is NULL or an - * empty string, "", the function sets the type and data for the - * key's unnamed or default value. - * @param Reserved - * Reserved; must be zero. - * @param dwType - * Type of data pointed to by the lpData parameter. - * @param lpData - * Pointer to a buffer containing the data to be stored with the - * specified value name. - * @param cbData - * Size of the information pointed to by the lpData parameter, in - * bytes. If the data is of type REG_SZ, REG_EXPAND_SZ, or - * REG_MULTI_SZ, cbData must include the size of the terminating - * null character or characters. - * @return If the function succeeds, the return value is ERROR_SUCCESS. If - * the function fails, the return value is a nonzero error code - * defined in Winerror.h. - */ - public int RegSetValueEx(HKEY hKey, String lpValueName, int Reserved, - int dwType, char[] lpData, int cbData); - - public int RegSetValueEx(HKEY hKey, String lpValueName, int Reserved, - int dwType, byte[] lpData, int cbData); - - /** - * - * @param hKey registry key - * @param lpSubKey subkey name - * @param Reserved unused - * @param lpClass class - * @param dwOptions options - * @param samDesired ? - * @param lpSecurityAttributes security attributes - * @param phkResult resulting key - * @param lpdwDisposition ? - * @return If the function succeeds, the return value is ERROR_SUCCESS. If - * the function fails, the return value is a nonzero error code - * defined in Winerror.h. - */ - public int RegCreateKeyEx(HKEY hKey, String lpSubKey, int Reserved, - String lpClass, int dwOptions, int samDesired, - SECURITY_ATTRIBUTES lpSecurityAttributes, - HKEYByReference phkResult, IntByReference lpdwDisposition); - - /** - * - * @param hKey registry key - * @param name key name - * @return If the function succeeds, the return value is ERROR_SUCCESS. If - * the function fails, the return value is a nonzero error code - * defined in Winerror.h. - */ - public int RegDeleteKey(HKEY hKey, String name); - - /** - * The RegEnumKeyEx function enumerates subkeys of the specified open - * registry key. The function retrieves information about one subkey each - * time it is called. - * - * @param hKey - * Handle to an open key. The key must have been opened with the - * KEY_ENUMERATE_SUB_KEYS access right. - * @param dwIndex - * Index of the subkey to retrieve. This parameter should be zero - * for the first call to the RegEnumKeyEx function and then - * incremented for subsequent calls. Because subkeys are not - * ordered, any new subkey will have an arbitrary index. This - * means that the function may return subkeys in any order. - * @param lpName - * Pointer to a buffer that receives the name of the subkey, - * including the terminating null character. The function copies - * only the name of the subkey, not the full key hierarchy, to - * the buffer. - * @param lpcName - * Pointer to a variable that specifies the size of the buffer - * specified by the lpName parameter, in TCHARs. This size should - * include the terminating null character. When the function - * returns, the variable pointed to by lpcName contains the - * number of characters stored in the buffer. The count returned - * does not include the terminating null character. - * @param reserved - * Reserved; must be NULL. - * @param lpClass - * Pointer to a buffer that receives the null-terminated class - * string of the enumerated subkey. This parameter can be NULL. - * @param lpcClass - * Pointer to a variable that specifies the size of the buffer - * specified by the lpClass parameter, in TCHARs. The size should - * include the terminating null character. When the function - * returns, lpcClass contains the number of characters stored in - * the buffer. The count returned does not include the - * terminating null character. This parameter can be NULL only if - * lpClass is NULL. - * @param lpftLastWriteTime - * Pointer to a variable that receives the time at which the - * enumerated subkey was last written. - * @return If the function succeeds, the return value is ERROR_SUCCESS. If - * the function fails, the return value is a nonzero error code - * defined in Winerror.h. - */ - public int RegEnumKeyEx(HKEY hKey, int dwIndex, char[] lpName, - IntByReference lpcName, IntByReference reserved, char[] lpClass, - IntByReference lpcClass, WinBase.FILETIME lpftLastWriteTime); - - /** - * The RegEnumValue function enumerates the values for the specified open - * registry key. The function copies one indexed value name and data block - * for the key each time it is called. - * - * @param hKey - * Handle to an open key. The key must have been opened with the - * KEY_QUERY_VALUE access right. - * @param dwIndex - * Index of the value to be retrieved. This parameter should be - * zero for the first call to the RegEnumValue function and then - * be incremented for subsequent calls. Because values are not - * ordered, any new value will have an arbitrary index. This - * means that the function may return values in any order. - * @param lpValueName - * Pointer to a buffer that receives the name of the value, - * including the terminating null character. - * @param lpcchValueName - * Pointer to a variable that specifies the size of the buffer - * pointed to by the lpValueName parameter, in TCHARs. This size - * should include the terminating null character. When the - * function returns, the variable pointed to by lpcValueName - * contains the number of characters stored in the buffer. The - * count returned does not include the terminating null - * character. - * @param reserved - * Reserved; must be NULL. - * @param lpType - * Pointer to a variable that receives a code indicating the type - * of data stored in the specified value. - * @param lpData - * Pointer to a buffer that receives the data for the value - * entry. This parameter can be NULL if the data is not required. - * @param lpcbData - * Pointer to a variable that specifies the size of the buffer - * pointed to by the lpData parameter, in bytes. - * @return If the function succeeds, the return value is ERROR_SUCCESS. If - * the function fails, the return value is a nonzero error code - * defined in Winerror.h. - */ - public int RegEnumValue(HKEY hKey, int dwIndex, char[] lpValueName, - IntByReference lpcchValueName, IntByReference reserved, - IntByReference lpType, byte[] lpData, IntByReference lpcbData); + /** + * The RegCloseKey function releases a handle to the specified registry key. + * + * @param hKey + * Handle to the open key to be closed. The handle must have been + * opened by the RegCreateKeyEx, RegOpenKeyEx, or + * RegConnectRegistry function. + * @return If the function succeeds, the return value is ERROR_SUCCESS. If + * the function fails, the return value is a nonzero error code + * defined in Winerror.h. + */ + int RegCloseKey(HKEY hKey); - /** - * The RegQueryInfoKey function retrieves information about the specified - * registry key. - * - * @param hKey - * A handle to an open key. The key must have been opened with - * the KEY_QUERY_VALUE access right. - * @param lpClass - * A pointer to a buffer that receives the null-terminated class - * string of the key. This parameter can be ignored. This - * parameter can be NULL. - * @param lpcClass - * A pointer to a variable that specifies the size of the buffer - * pointed to by the lpClass parameter, in characters. - * @param lpReserved - * Reserved; must be NULL. - * @param lpcSubKeys - * A pointer to a variable that receives the number of subkeys - * that are contained by the specified key. This parameter can be - * NULL. - * @param lpcMaxSubKeyLen - * A pointer to a variable that receives the size of the key's - * subkey with the longest name, in characters, not including the - * terminating null character. This parameter can be NULL. - * @param lpcMaxClassLen - * A pointer to a variable that receives the size of the longest - * string that specifies a subkey class, in characters. The count - * returned does not include the terminating null character. This - * parameter can be NULL. - * @param lpcValues - * A pointer to a variable that receives the number of values - * that are associated with the key. This parameter can be NULL. - * @param lpcMaxValueNameLen - * A pointer to a variable that receives the size of the key's - * longest value name, in characters. The size does not include - * the terminating null character. This parameter can be NULL. - * @param lpcMaxValueLen - * A pointer to a variable that receives the size of the longest - * data component among the key's values, in bytes. This - * parameter can be NULL. - * @param lpcbSecurityDescriptor - * A pointer to a variable that receives the size of the key's - * security descriptor, in bytes. This parameter can be NULL. - * @param lpftLastWriteTime - * A pointer to a FILETIME structure that receives the last write - * time. This parameter can be NULL. - * @return If the function succeeds, the return value is ERROR_SUCCESS. If - * the function fails, the return value is a nonzero error code - * defined in Winerror.h. - */ - public int RegQueryInfoKey(HKEY hKey, char[] lpClass, + /** + * The RegDeleteValue function removes a named value from the specified + * registry key. Note that value names are not case sensitive. + * + * @param hKey + * Handle to an open key. The key must have been opened with the + * KEY_SET_VALUE access right. + * @param lpValueName + * Pointer to a null-terminated string that names the value to + * remove. If this parameter is NULL or an empty string, the + * value set by the RegSetValue function is removed. + * @return If the function succeeds, the return value is ERROR_SUCCESS. If + * the function fails, the return value is a nonzero error code + * defined in Winerror.h. + */ + int RegDeleteValue(HKEY hKey, String lpValueName); + + /** + * The RegSetValueEx function sets the data and type of a specified value + * under a registry key. + * + * @param hKey + * Handle to an open key. The key must have been opened with the + * KEY_SET_VALUE access right. + * @param lpValueName + * Pointer to a string containing the name of the value to set. + * If a value with this name is not already present in the key, + * the function adds it to the key. If lpValueName is NULL or an + * empty string, "", the function sets the type and data for the + * key's unnamed or default value. + * @param Reserved + * Reserved; must be zero. + * @param dwType + * Type of data pointed to by the lpData parameter. + * @param lpData + * Pointer to a buffer containing the data to be stored with the + * specified value name. + * @param cbData + * Size of the information pointed to by the lpData parameter, in + * bytes. If the data is of type REG_SZ, REG_EXPAND_SZ, or + * REG_MULTI_SZ, cbData must include the size of the terminating + * null character or characters. + * @return If the function succeeds, the return value is ERROR_SUCCESS. If + * the function fails, the return value is a nonzero error code + * defined in Winerror.h. + */ + int RegSetValueEx(HKEY hKey, String lpValueName, int Reserved, + int dwType, char[] lpData, int cbData); + + int RegSetValueEx(HKEY hKey, String lpValueName, int Reserved, + int dwType, byte[] lpData, int cbData); + + /** + * + * @param hKey registry key + * @param lpSubKey subkey name + * @param Reserved unused + * @param lpClass class + * @param dwOptions options + * @param samDesired ? + * @param lpSecurityAttributes security attributes + * @param phkResult resulting key + * @param lpdwDisposition ? + * @return If the function succeeds, the return value is ERROR_SUCCESS. If + * the function fails, the return value is a nonzero error code + * defined in Winerror.h. + */ + int RegCreateKeyEx(HKEY hKey, String lpSubKey, int Reserved, + String lpClass, int dwOptions, int samDesired, + SECURITY_ATTRIBUTES lpSecurityAttributes, + HKEYByReference phkResult, IntByReference lpdwDisposition); + + /** + * + * @param hKey registry key + * @param name key name + * @return If the function succeeds, the return value is ERROR_SUCCESS. If + * the function fails, the return value is a nonzero error code + * defined in Winerror.h. + */ + int RegDeleteKey(HKEY hKey, String name); + + /** + * The RegEnumKeyEx function enumerates subkeys of the specified open + * registry key. The function retrieves information about one subkey each + * time it is called. + * + * @param hKey + * Handle to an open key. The key must have been opened with the + * KEY_ENUMERATE_SUB_KEYS access right. + * @param dwIndex + * Index of the subkey to retrieve. This parameter should be zero + * for the first call to the RegEnumKeyEx function and then + * incremented for subsequent calls. Because subkeys are not + * ordered, any new subkey will have an arbitrary index. This + * means that the function may return subkeys in any order. + * @param lpName + * Pointer to a buffer that receives the name of the subkey, + * including the terminating null character. The function copies + * only the name of the subkey, not the full key hierarchy, to + * the buffer. + * @param lpcName + * Pointer to a variable that specifies the size of the buffer + * specified by the lpName parameter, in TCHARs. This size should + * include the terminating null character. When the function + * returns, the variable pointed to by lpcName contains the + * number of characters stored in the buffer. The count returned + * does not include the terminating null character. + * @param reserved + * Reserved; must be NULL. + * @param lpClass + * Pointer to a buffer that receives the null-terminated class + * string of the enumerated subkey. This parameter can be NULL. + * @param lpcClass + * Pointer to a variable that specifies the size of the buffer + * specified by the lpClass parameter, in TCHARs. The size should + * include the terminating null character. When the function + * returns, lpcClass contains the number of characters stored in + * the buffer. The count returned does not include the + * terminating null character. This parameter can be NULL only if + * lpClass is NULL. + * @param lpftLastWriteTime + * Pointer to a variable that receives the time at which the + * enumerated subkey was last written. + * @return If the function succeeds, the return value is ERROR_SUCCESS. If + * the function fails, the return value is a nonzero error code + * defined in Winerror.h. + */ + int RegEnumKeyEx(HKEY hKey, int dwIndex, char[] lpName, + IntByReference lpcName, IntByReference reserved, char[] lpClass, + IntByReference lpcClass, WinBase.FILETIME lpftLastWriteTime); + + /** + * The RegEnumValue function enumerates the values for the specified open + * registry key. The function copies one indexed value name and data block + * for the key each time it is called. + * + * @param hKey + * Handle to an open key. The key must have been opened with the + * KEY_QUERY_VALUE access right. + * @param dwIndex + * Index of the value to be retrieved. This parameter should be + * zero for the first call to the RegEnumValue function and then + * be incremented for subsequent calls. Because values are not + * ordered, any new value will have an arbitrary index. This + * means that the function may return values in any order. + * @param lpValueName + * Pointer to a buffer that receives the name of the value, + * including the terminating null character. + * @param lpcchValueName + * Pointer to a variable that specifies the size of the buffer + * pointed to by the lpValueName parameter, in TCHARs. This size + * should include the terminating null character. When the + * function returns, the variable pointed to by lpcValueName + * contains the number of characters stored in the buffer. The + * count returned does not include the terminating null + * character. + * @param reserved + * Reserved; must be NULL. + * @param lpType + * Pointer to a variable that receives a code indicating the type + * of data stored in the specified value. + * @param lpData + * Pointer to a buffer that receives the data for the value + * entry. This parameter can be NULL if the data is not required. + * @param lpcbData + * Pointer to a variable that specifies the size of the buffer + * pointed to by the lpData parameter, in bytes. + * @return If the function succeeds, the return value is ERROR_SUCCESS. If + * the function fails, the return value is a nonzero error code + * defined in Winerror.h. + */ + int RegEnumValue(HKEY hKey, int dwIndex, char[] lpValueName, + IntByReference lpcchValueName, IntByReference reserved, + IntByReference lpType, byte[] lpData, IntByReference lpcbData); + + /** + * The RegQueryInfoKey function retrieves information about the specified + * registry key. + * + * @param hKey + * A handle to an open key. The key must have been opened with + * the KEY_QUERY_VALUE access right. + * @param lpClass + * A pointer to a buffer that receives the null-terminated class + * string of the key. This parameter can be ignored. This + * parameter can be NULL. + * @param lpcClass + * A pointer to a variable that specifies the size of the buffer + * pointed to by the lpClass parameter, in characters. + * @param lpReserved + * Reserved; must be NULL. + * @param lpcSubKeys + * A pointer to a variable that receives the number of subkeys + * that are contained by the specified key. This parameter can be + * NULL. + * @param lpcMaxSubKeyLen + * A pointer to a variable that receives the size of the key's + * subkey with the longest name, in characters, not including the + * terminating null character. This parameter can be NULL. + * @param lpcMaxClassLen + * A pointer to a variable that receives the size of the longest + * string that specifies a subkey class, in characters. The count + * returned does not include the terminating null character. This + * parameter can be NULL. + * @param lpcValues + * A pointer to a variable that receives the number of values + * that are associated with the key. This parameter can be NULL. + * @param lpcMaxValueNameLen + * A pointer to a variable that receives the size of the key's + * longest value name, in characters. The size does not include + * the terminating null character. This parameter can be NULL. + * @param lpcMaxValueLen + * A pointer to a variable that receives the size of the longest + * data component among the key's values, in bytes. This + * parameter can be NULL. + * @param lpcbSecurityDescriptor + * A pointer to a variable that receives the size of the key's + * security descriptor, in bytes. This parameter can be NULL. + * @param lpftLastWriteTime + * A pointer to a FILETIME structure that receives the last write + * time. This parameter can be NULL. + * @return If the function succeeds, the return value is ERROR_SUCCESS. If + * the function fails, the return value is a nonzero error code + * defined in Winerror.h. + */ + int RegQueryInfoKey(HKEY hKey, char[] lpClass, IntByReference lpcClass, IntByReference lpReserved, IntByReference lpcSubKeys, IntByReference lpcMaxSubKeyLen, IntByReference lpcMaxClassLen, IntByReference lpcValues, @@ -810,927 +1160,1191 @@ IntByReference lpcbSecurityDescriptor, WinBase.FILETIME lpftLastWriteTime); - /** - * Retrieves the type and data for the specified registry value. - * - * @param hkey - * [in] A handle to an open registry key. The key must have been - * opened with the KEY_QUERY_VALUE access right. For more - * information, see Registry Key Security and Access Rights. - * - * This handle is returned by the RegCreateKeyEx, - * RegCreateKeyTransacted, RegOpenKeyEx, or RegOpenKeyTransacted - * function. It can also be one of the following predefined keys: - * - * HKEY_CLASSES_ROOT HKEY_CURRENT_CONFIG HKEY_CURRENT_USER - * HKEY_LOCAL_MACHINE HKEY_PERFORMANCE_DATA - * HKEY_PERFORMANCE_NLSTEXT HKEY_PERFORMANCE_TEXT HKEY_USERS - * - * @param lpSubKey - * [in, optional] The name of the registry key. This key must be - * a subkey of the key specified by the hkey parameter. - * - * Key names are not case sensitive. - * - * @param lpValue - * [in, optional] - * - * The name of the registry value. - * - * If this parameter is NULL or an empty string, "", the function - * retrieves the type and data for the key's unnamed or default - * value, if any. - * - * For more information, see Registry Element Size Limits. - * - * Keys do not automatically have an unnamed or default value. - * Unnamed values can be of any type. - * - * @param dwFlags - * [in, optional] - * - * The flags that restrict the data type of value to be queried. - * If the data type of the value does not meet this criteria, the - * function fails. This parameter can be one or more of the - * following values. - * - * RRF_RT_ANY 0x0000ffff No type restriction. RRF_RT_DWORD - * 0x00000018 Restrict type to 32-bit - * RRF_RT_REG_BINARY|RRF_RT_REG_DWORD. RRF_RT_QWORD 0x00000048 - * Restrict type to 64-bit RRF_RT_REG_BINARY | RRF_RT_REG_DWORD. - * RRF_RT_REG_BINARY 0x00000008 Restrict type to REG_BINARY. - * RRF_RT_REG_DWORD 0x00000010 Restrict type to REG_DWORD. - * RRF_RT_REG_EXPAND_SZ 0x00000004 Restrict type to - * REG_EXPAND_SZ. RRF_RT_REG_MULTI_SZ 0x00000020 Restrict type to - * REG_MULTI_SZ. RRF_RT_REG_NONE 0x00000001 Restrict type to - * REG_NONE. RRF_RT_REG_QWORD 0x00000040 Restrict type to - * REG_QWORD. RRF_RT_REG_SZ 0x00000002 Restrict type to REG_SZ. - * - * This parameter can also include one or more of the following - * values. RRF_NOEXPAND 0x10000000 - * - * Do not automatically expand environment strings if the value - * is of type REG_EXPAND_SZ. - * - * RRF_ZEROONFAILURE 0x20000000 - * - * If pvData is not NULL, set the contents of the buffer to - * zeroes on failure. - * - * @param pdwType - * [out, optional] - * - * A pointer to a variable that receives a code indicating the - * type of data stored in the specified value. For a list of the - * possible type codes, see Registry Value Types. This parameter - * can be NULL if the type is not required. - * - * @param pvData - * [out, optional] - * - * A pointer to a buffer that receives the value's data. This - * parameter can be NULL if the data is not required. - * - * If the data is a string, the function checks for a terminating - * null character. If one is not found, the string is stored with - * a null terminator if the buffer is large enough to accommodate - * the extra character. Otherwise, the function fails and returns - * ERROR_MORE_DATA. - * - * @param pcbData - * [in, out, optional] - * - * A pointer to a variable that specifies the size of the buffer - * pointed to by the pvData parameter, in bytes. When the - * function returns, this variable contains the size of the data - * copied to pvData. - * - * The pcbData parameter can be NULL only if pvData is NULL. - * - * If the data has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ - * type, this size includes any terminating null character or - * characters. For more information, see Remarks. - * - * If the buffer specified by pvData parameter is not large - * enough to hold the data, the function returns ERROR_MORE_DATA - * and stores the required buffer size in the variable pointed to - * by pcbData. In this case, the contents of the pvData buffer - * are undefined. - * - * If pvData is NULL, and pcbData is non-NULL, the function - * returns ERROR_SUCCESS and stores the size of the data, in - * bytes, in the variable pointed to by pcbData. This enables an - * application to determine the best way to allocate a buffer for - * the value's data. - * - * If hKey specifies HKEY_PERFORMANCE_DATA and the pvData buffer - * is not large enough to contain all of the returned data, the - * function returns ERROR_MORE_DATA and the value returned - * through the pcbData parameter is undefined. This is because - * the size of the performance data can change from one call to - * the next. In this case, you must increase the buffer size and - * call RegGetValue again passing the updated buffer size in the - * pcbData parameter. Repeat this until the function succeeds. - * You need to maintain a separate variable to keep track of the - * buffer size, because the value returned by pcbData is - * unpredictable. - * - * Return value If the function succeeds, the return value is - * ERROR_SUCCESS. If the function fails, the return value is a - * system error code. If the pvData buffer is too small to - * receive the value, the function returns ERROR_MORE_DATA. - * @return status - */ - public int RegGetValue(HKEY hkey, String lpSubKey, String lpValue, - int dwFlags, IntByReference pdwType, byte[] pvData, - IntByReference pcbData); - - /** - * Retrieves a registered handle to the specified event log. - * - * @param lpUNCServerName - * The Universal Naming Convention (UNC) name of the remote - * server on which this operation is to be performed. If this - * parameter is NULL, the local computer is used. - * @param lpSourceName - * The name of the event source whose handle is to be retrieved. - * The source name must be a subkey of a log under the Eventlog - * registry key. However, the Security log is for system use - * only. - * @return If the function succeeds, the return value is a handle to the - * event log. If the function fails, the return value is NULL. To - * get extended error information, call GetLastError. The function - * returns ERROR_ACCESS_DENIED if lpSourceName specifies the - * Security event log. - */ - public HANDLE RegisterEventSource(String lpUNCServerName, - String lpSourceName); - - /** - * Closes the specified event log. - * - * @param hEventLog - * A handle to the event log. The RegisterEventSource function - * returns this handle. - * @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. - */ - public boolean DeregisterEventSource(HANDLE hEventLog); - - /** - * Opens a handle to the specified event log. - * - * @param lpUNCServerName - * The Universal Naming Convention (UNC) name of the remote - * server on which the event log is to be opened. If this - * parameter is NULL, the local computer is used. - * @param lpSourceName - * The name of the log. If you specify a custom log and it cannot - * be found, the event logging service opens the Application log; - * however, there will be no associated message or category - * string file. - * @return If the function succeeds, the return value is the handle to an - * event log. If the function fails, the return value is NULL. To - * get extended error information, call GetLastError. - */ - public HANDLE OpenEventLog(String lpUNCServerName, String lpSourceName); - - /** - * Closes the specified event log. - * - * @param hEventLog - * A handle to the event log to be closed. The OpenEventLog or - * OpenBackupEventLog function returns this handle. - * @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. - */ - public boolean CloseEventLog(HANDLE hEventLog); - - /** - * Retrieves the number of records in the specified event log. - * - * @param hEventLog - * A handle to the open event log. The OpenEventLog or - * OpenBackupEventLog function returns this handle. - * @param NumberOfRecords - * A pointer to a variable that receives the number of records in - * the specified event log. - * @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. - */ - public boolean GetNumberOfEventLogRecords(HANDLE hEventLog, - IntByReference NumberOfRecords); - - /** - * Writes an entry at the end of the specified event log. - * - * @param hEventLog - * A handle to the event log. The RegisterEventSource function - * returns this handle. As of Windows XP with SP2, this parameter - * cannot be a handle to the Security log. To write an event to - * the Security log, use the AuthzReportSecurityEvent function. - * @param wType - * The type of event to be logged. - * @param wCategory - * The event category. This is source-specific information; the - * category can have any value. - * @param dwEventID - * The event identifier. The event identifier specifies the entry - * in the message file associated with the event source. - * @param lpUserSid - * A pointer to the current user's security identifier. This - * parameter can be NULL if the security identifier is not - * required. - * @param wNumStrings - * The number of insert strings in the array pointed to by the - * lpStrings parameter. A value of zero indicates that no strings - * are present. - * @param dwDataSize - * The number of bytes of event-specific raw (binary) data to - * write to the log. If this parameter is zero, no event-specific - * data is present. - * @param lpStrings - * A pointer to a buffer containing an array of null-terminated - * strings that are merged into the message before Event Viewer - * displays the string to the user. This parameter must be a - * valid pointer (or NULL), even if wNumStrings is zero. Each - * string is limited to 31,839 characters. - * @param lpRawData - * A pointer to the buffer containing the binary data. This - * parameter must be a valid pointer (or NULL), even if the - * dwDataSize parameter is zero. - * @return If the function succeeds, the return value is nonzero, indicating - * that the entry was written to the log. If the function fails, the - * return value is zero. To get extended error information, call - * GetLastError. - */ - public boolean ReportEvent(HANDLE hEventLog, int wType, int wCategory, + /** + * Retrieves the type and data for the specified registry value. + * + * @param hkey + * [in] A handle to an open registry key. The key must have been + * opened with the KEY_QUERY_VALUE access right. For more + * information, see Registry Key Security and Access Rights. + * + * This handle is returned by the RegCreateKeyEx, + * RegCreateKeyTransacted, RegOpenKeyEx, or RegOpenKeyTransacted + * function. It can also be one of the following predefined keys: + * + * HKEY_CLASSES_ROOT HKEY_CURRENT_CONFIG HKEY_CURRENT_USER + * HKEY_LOCAL_MACHINE HKEY_PERFORMANCE_DATA + * HKEY_PERFORMANCE_NLSTEXT HKEY_PERFORMANCE_TEXT HKEY_USERS + * + * @param lpSubKey + * [in, optional] The name of the registry key. This key must be + * a subkey of the key specified by the hkey parameter. + * + * Key names are not case sensitive. + * + * @param lpValue + * [in, optional] + * + * The name of the registry value. + * + * If this parameter is NULL or an empty string, "", the function + * retrieves the type and data for the key's unnamed or default + * value, if any. + * + * For more information, see Registry Element Size Limits. + * + * Keys do not automatically have an unnamed or default value. + * Unnamed values can be of any type. + * + * @param dwFlags + * [in, optional] + * + * The flags that restrict the data type of value to be queried. + * If the data type of the value does not meet this criteria, the + * function fails. This parameter can be one or more of the + * following values. + * + * RRF_RT_ANY 0x0000ffff No type restriction. RRF_RT_DWORD + * 0x00000018 Restrict type to 32-bit + * RRF_RT_REG_BINARY|RRF_RT_REG_DWORD. RRF_RT_QWORD 0x00000048 + * Restrict type to 64-bit RRF_RT_REG_BINARY | RRF_RT_REG_DWORD. + * RRF_RT_REG_BINARY 0x00000008 Restrict type to REG_BINARY. + * RRF_RT_REG_DWORD 0x00000010 Restrict type to REG_DWORD. + * RRF_RT_REG_EXPAND_SZ 0x00000004 Restrict type to + * REG_EXPAND_SZ. RRF_RT_REG_MULTI_SZ 0x00000020 Restrict type to + * REG_MULTI_SZ. RRF_RT_REG_NONE 0x00000001 Restrict type to + * REG_NONE. RRF_RT_REG_QWORD 0x00000040 Restrict type to + * REG_QWORD. RRF_RT_REG_SZ 0x00000002 Restrict type to REG_SZ. + * + * This parameter can also include one or more of the following + * values. RRF_NOEXPAND 0x10000000 + * + * Do not automatically expand environment strings if the value + * is of type REG_EXPAND_SZ. + * + * RRF_ZEROONFAILURE 0x20000000 + * + * If pvData is not NULL, set the contents of the buffer to + * zeroes on failure. + * + * @param pdwType + * [out, optional] + * + * A pointer to a variable that receives a code indicating the + * type of data stored in the specified value. For a list of the + * possible type codes, see Registry Value Types. This parameter + * can be NULL if the type is not required. + * + * @param pvData + * [out, optional] + * + * A pointer to a buffer that receives the value's data. This + * parameter can be NULL if the data is not required. + * + * If the data is a string, the function checks for a terminating + * null character. If one is not found, the string is stored with + * a null terminator if the buffer is large enough to accommodate + * the extra character. Otherwise, the function fails and returns + * ERROR_MORE_DATA. + * + * @param pcbData + * [in, out, optional] + * + * A pointer to a variable that specifies the size of the buffer + * pointed to by the pvData parameter, in bytes. When the + * function returns, this variable contains the size of the data + * copied to pvData. + * + * The pcbData parameter can be NULL only if pvData is NULL. + * + * If the data has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ + * type, this size includes any terminating null character or + * characters. For more information, see Remarks. + * + * If the buffer specified by pvData parameter is not large + * enough to hold the data, the function returns ERROR_MORE_DATA + * and stores the required buffer size in the variable pointed to + * by pcbData. In this case, the contents of the pvData buffer + * are undefined. + * + * If pvData is NULL, and pcbData is non-NULL, the function + * returns ERROR_SUCCESS and stores the size of the data, in + * bytes, in the variable pointed to by pcbData. This enables an + * application to determine the best way to allocate a buffer for + * the value's data. + * + * If hKey specifies HKEY_PERFORMANCE_DATA and the pvData buffer + * is not large enough to contain all of the returned data, the + * function returns ERROR_MORE_DATA and the value returned + * through the pcbData parameter is undefined. This is because + * the size of the performance data can change from one call to + * the next. In this case, you must increase the buffer size and + * call RegGetValue again passing the updated buffer size in the + * pcbData parameter. Repeat this until the function succeeds. + * You need to maintain a separate variable to keep track of the + * buffer size, because the value returned by pcbData is + * unpredictable. + * + * Return value If the function succeeds, the return value is + * ERROR_SUCCESS. If the function fails, the return value is a + * system error code. If the pvData buffer is too small to + * receive the value, the function returns ERROR_MORE_DATA. + * @return status + */ + int RegGetValue(HKEY hkey, String lpSubKey, String lpValue, + int dwFlags, IntByReference pdwType, byte[] pvData, + IntByReference pcbData); + + /** + * Retrieves a registered handle to the specified event log. + * + * @param lpUNCServerName + * The Universal Naming Convention (UNC) name of the remote + * server on which this operation is to be performed. If this + * parameter is NULL, the local computer is used. + * @param lpSourceName + * The name of the event source whose handle is to be retrieved. + * The source name must be a subkey of a log under the Eventlog + * registry key. However, the Security log is for system use + * only. + * @return If the function succeeds, the return value is a handle to the + * event log. If the function fails, the return value is NULL. To + * get extended error information, call GetLastError. The function + * returns ERROR_ACCESS_DENIED if lpSourceName specifies the + * Security event log. + */ + HANDLE RegisterEventSource(String lpUNCServerName, String lpSourceName); + + /** + * Closes the specified event log. + * + * @param hEventLog + * A handle to the event log. The RegisterEventSource function + * returns this handle. + * @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. + */ + boolean DeregisterEventSource(HANDLE hEventLog); + + /** + * Opens a handle to the specified event log. + * + * @param lpUNCServerName + * The Universal Naming Convention (UNC) name of the remote + * server on which the event log is to be opened. If this + * parameter is NULL, the local computer is used. + * @param lpSourceName + * The name of the log. If you specify a custom log and it cannot + * be found, the event logging service opens the Application log; + * however, there will be no associated message or category + * string file. + * @return If the function succeeds, the return value is the handle to an + * event log. If the function fails, the return value is NULL. To + * get extended error information, call GetLastError. + */ + HANDLE OpenEventLog(String lpUNCServerName, String lpSourceName); + + /** + * Closes the specified event log. + * + * @param hEventLog + * A handle to the event log to be closed. The OpenEventLog or + * OpenBackupEventLog function returns this handle. + * @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. + */ + boolean CloseEventLog(HANDLE hEventLog); + + /** + * Retrieves the number of records in the specified event log. + * + * @param hEventLog + * A handle to the open event log. The OpenEventLog or + * OpenBackupEventLog function returns this handle. + * @param NumberOfRecords + * A pointer to a variable that receives the number of records in + * the specified event log. + * @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. + */ + boolean GetNumberOfEventLogRecords(HANDLE hEventLog, IntByReference NumberOfRecords); + + /** + * Writes an entry at the end of the specified event log. + * + * @param hEventLog + * A handle to the event log. The RegisterEventSource function + * returns this handle. As of Windows XP with SP2, this parameter + * cannot be a handle to the Security log. To write an event to + * the Security log, use the AuthzReportSecurityEvent function. + * @param wType + * The type of event to be logged. + * @param wCategory + * The event category. This is source-specific information; the + * category can have any value. + * @param dwEventID + * The event identifier. The event identifier specifies the entry + * in the message file associated with the event source. + * @param lpUserSid + * A pointer to the current user's security identifier. This + * parameter can be NULL if the security identifier is not + * required. + * @param wNumStrings + * The number of insert strings in the array pointed to by the + * lpStrings parameter. A value of zero indicates that no strings + * are present. + * @param dwDataSize + * The number of bytes of event-specific raw (binary) data to + * write to the log. If this parameter is zero, no event-specific + * data is present. + * @param lpStrings + * A pointer to a buffer containing an array of null-terminated + * strings that are merged into the message before Event Viewer + * displays the string to the user. This parameter must be a + * valid pointer (or NULL), even if wNumStrings is zero. Each + * string is limited to 31,839 characters. + * @param lpRawData + * A pointer to the buffer containing the binary data. This + * parameter must be a valid pointer (or NULL), even if the + * dwDataSize parameter is zero. + * @return If the function succeeds, the return value is nonzero, indicating + * that the entry was written to the log. If the function fails, the + * return value is zero. To get extended error information, call + * GetLastError. + */ + boolean ReportEvent(HANDLE hEventLog, int wType, int wCategory, int dwEventID, PSID lpUserSid, int wNumStrings, int dwDataSize, String[] lpStrings, Pointer lpRawData); - /** - * Clears the specified event log, and optionally saves the current copy of - * the log to a backup file. - * - * @param hEventLog - * A handle to the event log to be cleared. The OpenEventLog - * function returns this handle. - * @param lpBackupFileName - * The absolute or relative path of the backup file. If this file - * already exists, the function fails. If the lpBackupFileName - * parameter is NULL, the event log is not backed up. - * @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. The ClearEventLog function can - * fail if the event log is empty or the backup file already exists. - */ - public boolean ClearEventLog(HANDLE hEventLog, String lpBackupFileName); - - /** - * Saves the specified event log to a backup file. The function does not - * clear the event log. - * - * @param hEventLog - * A handle to the open event log. The OpenEventLog function - * returns this handle. - * @param lpBackupFileName - * The absolute or relative path of the backup file. - * @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. - */ - public boolean BackupEventLog(HANDLE hEventLog, String lpBackupFileName); - - /** - * Opens a handle to a backup event log created by the BackupEventLog - * function. - * - * @param lpUNCServerName - * The Universal Naming Convention (UNC) name of the remote - * server on which this operation is to be performed. If this - * parameter is NULL, the local computer is used. - * @param lpFileName - * The full path of the backup file. - * @return If the function succeeds, the return value is a handle to the - * backup event log. If the function fails, the return value is - * NULL. To get extended error information, call GetLastError. - */ - public HANDLE OpenBackupEventLog(String lpUNCServerName, String lpFileName); - - /** - * Reads the specified number of entries from the specified event log. The - * function can be used to read log entries in chronological or reverse - * chronological order. - * - * @param hEventLog - * A handle to the event log to be read. The OpenEventLog - * function returns this handle. - * @param dwReadFlags - * Use the following flag values to indicate how to read the log - * file. - * @param dwRecordOffset - * The record number of the log-entry at which the read operation - * should start. This parameter is ignored unless dwReadFlags - * includes the EVENTLOG_SEEK_READ flag. - * @param lpBuffer - * An application-allocated buffer that will receive one or more - * EVENTLOGRECORD structures. This parameter cannot be NULL, even - * if the nNumberOfBytesToRead parameter is zero. The maximum - * size of this buffer is 0x7ffff bytes. - * @param nNumberOfBytesToRead - * The size of the lpBuffer buffer, in bytes. This function will - * read as many log entries as will fit in the buffer; the - * function will not return partial entries. - * @param pnBytesRead - * A pointer to a variable that receives the number of bytes read - * by the function. - * @param pnMinNumberOfBytesNeeded - * A pointer to a variable that receives the required size of the - * lpBuffer buffer. This value is valid only this function - * returns zero and GetLastError returns - * ERROR_INSUFFICIENT_BUFFER. - * @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. - */ - public boolean ReadEventLog(HANDLE hEventLog, int dwReadFlags, - int dwRecordOffset, Pointer lpBuffer, int nNumberOfBytesToRead, - IntByReference pnBytesRead, IntByReference pnMinNumberOfBytesNeeded); - - /** - * The GetOldestEventLogRecord function retrieves the absolute record number - * of the oldest record in the specified event log. - * - * @param hEventLog - * Handle to the open event log. This handle is returned by the - * OpenEventLog or OpenBackupEventLog function. - * @param OldestRecord - * Pointer to a variable that receives the absolute record number - * of the oldest record in the specified event log. - * @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. - */ - public boolean GetOldestEventLogRecord(HANDLE hEventLog, - IntByReference OldestRecord); - - /** - * Retrieves the current status of the specified service based on the - * specified information level. - * - * @param hService - * A handle to the service. This handle is returned by the - * OpenService(SC_HANDLE, String, int) or CreateService() - * function, and it must have the SERVICE_QUERY_STATUS access - * right. For more information, see Service Security and Access Rights. - * @param InfoLevel - * The service attributes to be returned (a value from - * SC_STATUS_TYPE enumeration). Use SC_STATUS_PROCESS_INFO to - * retrieve the service status information. The lpBuffer - * parameter is a pointer to a SERVICE_STATUS_PROCESS structure. - * Currently, no other information levels are defined. - * @param lpBuffer - * (optional) A pointer to the buffer that receives the status - * information. The format of this data depends on the value of - * the InfoLevel parameter. The maximum size of this array is 8K - * bytes. To determine the required size, specify NULL for this - * parameter and 0 for the cbBufSize parameter. The function will - * fail and GetLastError will return ERROR_INSUFFICIENT_BUFFER. - * The pcbBytesNeeded parameter will receive the required size. - * @param cbBufSize - * The size of the buffer pointed to by the lpBuffer parameter, - * in bytes. - * @param pcbBytesNeeded - * A pointer to a variable that receives the number of bytes - * needed to store all status information, if the function fails - * with ERROR_INSUFFICIENT_BUFFER. - * @return If the function succeeds, the return value is true. If the - * function fails, the return value is false. To get extended error - * information, call GetLastError. This value is a nonzero error - * code defined in Winerror.h. - */ - public boolean QueryServiceStatusEx(SC_HANDLE hService, int InfoLevel, - SERVICE_STATUS_PROCESS lpBuffer, int cbBufSize, - IntByReference pcbBytesNeeded); - - /** - * Sends a control code to a service. To specify additional information when - * stopping a service, use the ControlServiceEx function. - * - * @param hService - * A handle to the service. This handle is returned by the - * OpenService(SC_HANDLE, String, int) or CreateService() - * function. The access rights required for this handle depend on - * the dwControl code requested. - * @param dwControl - * This parameter can be one of the following control codes - * (found in Winsvc.h): SERVICE_CONTROL_STOP, - * SERVICE_CONTROL_PAUSE, SERVICE_CONTROL_CONTINUE - * SERVICE_CONTROL_INTERROGATE, SERVICE_CONTROL_PARAMCHANGE, - * SERVICE_CONTROL_NETBINDADD, SERVICE_CONTROL_NETBINDREMOVE, - * SERVICE_CONTROL_NETBINDENABLE, SERVICE_CONTROL_NETBINDDISABLE - * This value can also be a user-defined control code, as - * described below: Range 128 to 255 - The service defines the - * action associated with the control code. The hService handle - * must have the SERVICE_USER_DEFINED_CONTROL access right. - * @param lpServiceStatus - * A pointer to a SERVICE_STATUS structure that receives the - * latest service status information. The information returned - * reflects the most recent status that the service reported to - * the service control manager. The service control manager fills - * in the structure only when ControlService returns one of the - * following error codes: NO_ERROR, - * ERROR_INVALID_SERVICE_CONTROL, - * ERROR_SERVICE_CANNOT_ACCEPT_CTRL, or ERROR_SERVICE_NOT_ACTIVE. - * Otherwise, the structure is not filled in. - * @return If the function succeeds, the return value is true. If the - * function fails, the return value is false. To get extended error - * information, call GetLastError. This value is a nonzero error - * code defined in Winerror.h. - */ - public boolean ControlService(SC_HANDLE hService, int dwControl, - SERVICE_STATUS lpServiceStatus); - - /** - * Starts a service. - * - * @param hService - * A handle to the service. This handle is returned by the - * OpenService(SC_HANDLE, String, int) or CreateService() - * function, and it must have the SERVICE_START access right. For - * more information, see - * Service Security and Access Rights. - * @param dwNumServiceArgs - * The number of strings in the lpServiceArgVectors array. If - * lpServiceArgVectors is NULL, this parameter can be zero. - * @param lpServiceArgVectors - * The null-terminated strings to be passed to the ServiceMain - * function for the service as arguments. If there are no - * arguments, this parameter can be null. Otherwise, the first - * argument (lpServiceArgVectors[0]) is the name of the service, - * followed by any additional arguments (lpServiceArgVectors[1] - * through lpServiceArgVectors[dwNumServiceArgs-1]). Driver - * services do not receive these arguments. - * @return If the function succeeds, the return value is true. If the - * function fails, the return value is false. To get extended error - * information, call GetLastError. This value is a nonzero error - * code defined in Winerror.h. - */ - public boolean StartService(SC_HANDLE hService, int dwNumServiceArgs, - String[] lpServiceArgVectors); - - /** - * Closes a handle to a service control manager or service object. - * - * @param hSCObject - * A handle to the service control manager object or the service - * object to close. Handles to service control manager objects - * are returned by the OpenSCManager(String, String, int) - * function, and handles to service objects are returned by - * either the OpenService(SC_HANDLE, String, int) or - * CreateService() 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. This value is a nonzero error - * code defined in Winerror.h. - */ - public boolean CloseServiceHandle(SC_HANDLE hSCObject); - - /** - * Opens an existing service. - * - * @param hSCManager - * A handle to the service control manager database. The - * OpenSCManager(String, String, int) function returns this - * handle. - * @param lpServiceName - * The name of the service to be opened. This is the name - * specified by the lpServiceName parameter of the CreateService - * function when the service object was created, not the service - * display name that is shown by user interface applications to - * identify the service. The maximum string length is 256 - * characters. The service control manager database preserves the - * case of the characters, but service name comparisons are - * always case insensitive. Forward-slash (/) and backslash (\) - * are invalid service name characters. - * @param dwDesiredAccess - * The access to the service. For a list of access rights, see - * Service Security and Access Rights. Before granting the - * requested access, the system checks the access token of the - * calling process against the discretionary access-control list - * of the security descriptor associated with the service object. - * @return If the function succeeds, the return value is a handle to the - * service. If the function fails, the return value is NULL. To get - * extended error information, call GetLastError. This value is a - * nonzero error code defined in Winerror.h. - */ - public SC_HANDLE OpenService(SC_HANDLE hSCManager, String lpServiceName, - int dwDesiredAccess); - - /** - * Establishes a connection to the service control manager on the specified - * computer and opens the specified service control manager database. - * - * @param lpMachineName - * The name of the target computer. If the pointer is NULL or - * points to an empty string, the function connects to the - * service control manager on the local computer. - * @param lpDatabaseName - * The name of the service control manager database. This - * parameter should be set to SERVICES_ACTIVE_DATABASE. If it is - * NULL, the SERVICES_ACTIVE_DATABASE database is opened by - * default. - * @param dwDesiredAccess - * The access to the service control manager. For a list of - * access rights, see - * Service Security and Access Rights. Before granting the - * requested access rights, the system checks the access token of - * the calling process against the discretionary access-control - * list of the security descriptor associated with the service - * control manager. The SC_MANAGER_CONNECT access right is - * implicitly specified by calling this function. - * @return If the function succeeds, the return value is a handle to the - * specified service control manager database. If the function - * fails, the return value is NULL. To get extended error - * information, call GetLastError. This value is a nonzero error - * code defined in Winerror.h. - */ - public SC_HANDLE OpenSCManager(String lpMachineName, String lpDatabaseName, - int dwDesiredAccess); - - /** - * Creates a new process and its primary thread. The new process runs in the - * security context of the user represented by the specified token. - * - * Typically, the process that calls the CreateProcessAsUser function must - * have the SE_INCREASE_QUOTA_NAME privilege and may require the - * SE_ASSIGNPRIMARYTOKEN_NAME privilege if the token is not assignable. If - * this function fails with ERROR_PRIVILEGE_NOT_HELD (1314), use the - * CreateProcessWithLogonW function instead. CreateProcessWithLogonW - * requires no special privileges, but the specified user account must be - * allowed to log on interactively. Generally, it is best to use - * CreateProcessWithLogonW to create a process with alternate credentials. - * - * @param hToken - * A handle to the primary token that represents a user. - * @param lpApplicationName - * The name of the module to be executed. - * @param lpCommandLine - * The command line to be executed. - * @param lpProcessAttributes - * A pointer to a SECURITY_ATTRIBUTES structure that specifies a - * security descriptor for the new process object and determines - * whether child processes can inherit the returned handle to the - * process. - * @param lpThreadAttributes - * A pointer to a SECURITY_ATTRIBUTES structure that specifies a - * security descriptor for the new thread object and determines - * whether child processes can inherit the returned handle to the - * thread. - * @param bInheritHandles - * If this parameter is TRUE, each inheritable handle in the - * calling process is inherited by the new process. If the - * parameter is FALSE, the handles are not inherited. Note that - * inherited handles have the same value and access rights as the - * original handles. - * @param dwCreationFlags - * The flags that control the priority class and the creation of - * the process. For a list of values, see Process Creation Flags. - * @param lpEnvironment - * A pointer to an environment block for the new process. If this - * parameter is NULL, the new process uses the environment of the - * calling process. - * - * An environment block consists of a null-terminated block of - * null-terminated strings. Each string is in the following form: - * name=value\0 - * @param lpCurrentDirectory - * The full path to the current directory for the process. The - * string can also specify a UNC path. - * @param lpStartupInfo - * A pointer to a STARTUPINFO or STARTUPINFOEX structure. - * @param lpProcessInformation - * A pointer to a PROCESS_INFORMATION structure that receives - * identification information about the new process. - * @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. - */ - public boolean CreateProcessAsUser(HANDLE hToken, String lpApplicationName, - String lpCommandLine, SECURITY_ATTRIBUTES lpProcessAttributes, - SECURITY_ATTRIBUTES lpThreadAttributes, boolean bInheritHandles, - int dwCreationFlags, String lpEnvironment, - String lpCurrentDirectory, WinBase.STARTUPINFO lpStartupInfo, - WinBase.PROCESS_INFORMATION lpProcessInformation); - - /** - * The AdjustTokenPrivileges function enables or disables privileges in the - * specified access token. Enabling or disabling privileges in an access - * token requires TOKEN_ADJUST_PRIVILEGES access. - * - * @param TokenHandle - * A handle to the access token that contains the privileges to - * be modified. - * @param DisableAllPrivileges - * Specifies whether the function disables all of the token's - * privileges. - * @param NewState - * A pointer to a TOKEN_PRIVILEGES structure that specifies an - * array of privileges and their attributes. - * @param BufferLength - * Specifies the size, in bytes, of the buffer pointed to by the - * PreviousState parameter. This parameter can be zero if the - * PreviousState parameter is NULL. - * @param PreviousState - * A pointer to a buffer that the function fills with a - * TOKEN_PRIVILEGES structure that contains the previous state of - * any privileges that the function modifies. - * @param ReturnLength - * A pointer to a variable that receives the required size, in - * bytes, of the buffer pointed to by the PreviousState - * parameter. - * @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. - */ - public boolean AdjustTokenPrivileges(HANDLE TokenHandle, - boolean DisableAllPrivileges, WinNT.TOKEN_PRIVILEGES NewState, - int BufferLength, WinNT.TOKEN_PRIVILEGES PreviousState, - IntByReference ReturnLength); - - /** - * The LookupPrivilegeName function retrieves the name that corresponds to - * the privilege represented on a specific system by a specified locally - * unique identifier (LUID). - * - * @param lpSystemName - * A pointer to a null-terminated string that specifies the name - * of the system on which the privilege name is retrieved. If a - * null string is specified, the function attempts to find the - * privilege name on the local system. - * @param lpLuid - * A pointer to the LUID by which the privilege is known on the - * target system. - * @param lpName - * A pointer to a buffer that receives a null-terminated string - * that represents the privilege name. For example, this string - * could be "SeSecurityPrivilege". - * @param cchName - * A pointer to a variable that specifies the size, in a TCHAR - * value, of the lpName buffer. - * @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. - */ - public boolean LookupPrivilegeName(String lpSystemName, WinNT.LUID lpLuid, - char[] lpName, IntByReference cchName); - - /** - * The LookupPrivilegeValue function retrieves the locally unique identifier - * (LUID) used on a specified system to locally represent the specified - * privilege name. - * - * @param lpSystemName - * A pointer to a null-terminated string that specifies the name - * of the system on which the privilege name is retrieved. If a - * null string is specified, the function attempts to find the - * privilege name on the local system. - * @param lpName - * A pointer to a null-terminated string that specifies the name - * of the privilege, as defined in the Winnt.h header file. For - * example, this parameter could specify the constant, - * SE_SECURITY_NAME, or its corresponding string, - * "SeSecurityPrivilege". - * @param lpLuid - * A pointer to a variable that receives the LUID by which the - * privilege is known on the system specified by the lpSystemName - * parameter. - * @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. - */ - public boolean LookupPrivilegeValue(String lpSystemName, String lpName, - WinNT.LUID lpLuid); - - /** - * The function obtains specified information about the security of a file - * or directory. The information obtained is constrained by the caller's - * access rights and privileges. - * - * @param lpFileName - * A pointer to a null-terminated string that specifies the file - * or directory for which security information is retrieved. - * @param RequestedInformation - * A SECURITY_INFORMATION value that identifies the security - * information being requested. See WinNT *_SECURITY_INFORMATION - * @param pointer - * A pointer to a buffer that receives a copy of the security - * descriptor of the object specified by the lpFileName - * parameter. The calling process must have permission to view - * the specified aspects of the object's security status. The - * SECURITY_DESCRIPTOR structure is returned in self-relative - * format. - * @param nLength - * Specifies the size, in bytes, of the buffer pointed to by the - * pSecurityDescriptor parameter. - * @param lpnLengthNeeded - * A pointer to the variable that receives the number of bytes - * necessary to store the complete security descriptor. If the - * returned number of bytes is less than or equal to nLength, the - * entire security descriptor is returned in the output buffer; - * otherwise, none of the descriptor is returned. - * @return whether the call succeeded - */ - public boolean GetFileSecurity(WString lpFileName, - int RequestedInformation, Pointer pointer, int nLength, - IntByReference lpnLengthNeeded); - - /** - * The GetNamedSecurityInfo function retrieves a copy of the security - * descriptor for an object specified by name - * - * @param pObjectName - * A pointer to a that specifies the name of the object from - * which to retrieve security information. - * For descriptions of the string formats for the different - * object types, see SE_OBJECT_TYPE. - * @param ObjectType - * Specifies a value from the SE_OBJECT_TYPE enumeration that - * indicates the type of object named by the pObjectName parameter. - * @param SecurityInfo - * A set of bit flags that indicate the type of security - * information to retrieve. See WinNT *_SECURITY_INFORMATION - * @param ppsidOwner [out, optional] - * A pointer to a variable that receives a pointer to the owner SID - * in the security descriptor returned in ppSecurityDescriptor - * or NULL if the security descriptor has no owner SID. - * The returned pointer is valid only if you set the - * OWNER_SECURITY_INFORMATION flag. Also, this parameter can be - * NULL if you do not need the owner SID. - * @param ppsidGroup [out, optional] - * A pointer to a variable that receives a pointer to the primary - * group SID in the returned security descriptor or NULL if the - * security descriptor has no group SID. The returned pointer is - * valid only if you set the GROUP_SECURITY_INFORMATION flag. - * Also, this parameter can be NULL if you do not need the group SID. - * @param ppDacl [out, optional] - * A pointer to a variable that receives a pointer to the DACL in - * the returned security descriptor or NULL if the security - * descriptor has no DACL. The returned pointer is valid only if - * you set the DACL_SECURITY_INFORMATION flag. Also, this parameter - * can be NULL if you do not need the DACL. - * @param ppSacl [out, optional] - * A pointer to a variable that receives a pointer to the SACL in - * the returned security descriptor or NULL if the security - * descriptor has no SACL. The returned pointer is valid only if - * you set the SACL_SECURITY_INFORMATION flag. Also, this parameter - * can be NULL if you do not need the SACL. - * @param ppSecurityDescriptor - * A pointer to a variable that receives a pointer to the security - * descriptor of the object. When you have finished using the - * pointer, free the returned buffer by calling the LocalFree - * function. - * - * This parameter is required if any one of the ppsidOwner, - * ppsidGroup, ppDacl, or ppSacl parameters is not NULL. - * @return whether the call succeeded. A nonzero return is a failure. - * - * NOTES: - * 1. To read the owner, group, or DACL from the object's security descriptor, - * the object's DACL must grant READ_CONTROL access to the caller, or the caller - * must be the owner of the object. - * 2. To read the system access control list of the object, the SE_SECURITY_NAME - * privilege must be enabled for the calling process. For information about the - * security implications of enabling privileges, see Running with Special Privileges. - */ - public int GetNamedSecurityInfo( - String pObjectName, - int ObjectType, - int SecurityInfo, - PointerByReference ppsidOwner, - PointerByReference ppsidGroup, - PointerByReference ppDacl, - PointerByReference ppSacl, - PointerByReference ppSecurityDescriptor); - - /** - * The SetNamedSecurityInfo function sets specified security information in - * the security descriptor of a specified object. The caller identifies the - * object by name. - * - * @param pObjectName [in] - * A pointer to a string that specifies the name of the object for - * which to set security information. This can be - * the name of a local or remote file or directory on an NTFS file - * system, network share, registry key, semaphore, event, mutex, - * file mapping, or waitable timer. * - * For descriptions of the string formats for the different - * object types, see SE_OBJECT_TYPE. - * @param ObjectType [in] - * A value of the SE_OBJECT_TYPE enumeration that indicates the type - * of object named by the pObjectName parameter. - * @param SecurityInfo [in] - * A set of bit flags that indicate the type of security - * information to set. See WinNT *_SECURITY_INFORMATION - * @param ppsidOwner [in, optional] - * A pointer to a SID structure that identifies the owner of the object. - * If the caller does not have the SeRestorePrivilege constant - * (see Privilege Constants), this SID must be contained in the - * caller's token, and must have the SE_GROUP_OWNER permission enabled. - * The SecurityInfo parameter must include the OWNER_SECURITY_INFORMATION - * flag. To set the owner, the caller must have WRITE_OWNER access to - * the object or have the SE_TAKE_OWNERSHIP_NAME privilege enabled. - * If you are not setting the owner SID, this parameter can be NULL. - * @param ppsidGroup [in, optional] - * A pointer to a SID that identifies the primary group of the object. - * The SecurityInfo parameter must include the GROUP_SECURITY_INFORMATION - * flag. If you are not setting the primary group SID, this parameter - * can be NULL. - * @param ppDacl [in, optional] - * A pointer to the new DACL for the object. The SecurityInfo parameter - * must include the DACL_SECURITY_INFORMATION flag. The caller must have - * WRITE_DAC access to the object or be the owner of the object. If you - * are not setting the DACL, this parameter can be NULL. - * @param ppSacl [in, optional] - * A pointer to the new SACL for the object. The SecurityInfo parameter - * must include any of the following flags: SACL_SECURITY_INFORMATION, - * LABEL_SECURITY_INFORMATION, ATTRIBUTE_SECURITY_INFORMATION, - * SCOPE_SECURITY_INFORMATION, or BACKUP_SECURITY_INFORMATION. - * If setting SACL_SECURITY_INFORMATION or SCOPE_SECURITY_INFORMATION, - * the caller must have the SE_SECURITY_NAME privilege enabled. If - * you are not setting the SACL, this parameter can be NULL. - * @return whether the call succeeded. A nonzero return is a failure. - * - * NOTES: - * 1. The SetNamedSecurityInfo function does not reorder access-allowed or access-denied - * ACEs based on the preferred order. When propagating inheritable ACEs to existing - * child objects, SetNamedSecurityInfo puts inherited ACEs in order after all of the - * noninherited ACEs in the DACLs of the child objects. - * 2. This function transfers information in plaintext. The information transferred by - * this function is signed unless signing has been turned off for the system, but no - * encryption is performed. - * 3. When you update access rights of a folder indicated by an UNC path, for example - * \\Test\TestFolder, the original inherited ACE is removed and the full volume path - * is not included. - */ - public int SetNamedSecurityInfo( - String pObjectName, - int ObjectType, - int SecurityInfo, - Pointer ppsidOwner, - Pointer ppsidGroup, - Pointer ppDacl, - Pointer ppSacl); - - /** - * The GetSecurityDescriptorLength function returns the length, in bytes, of a structurally - * valid security descriptor. The length includes the length of all associated structures. - * - * @param ppSecurityDescriptor - * A pointer to the SECURITY_DESCRIPTOR structure whose length the function returns. - * The pointer is assumed to be valid. - * @return If the function succeeds, the function returns the length, in bytes, of the SECURITY_DESCRIPTOR structure. + /** + * Clears the specified event log, and optionally saves the current copy of + * the log to a backup file. + * + * @param hEventLog + * A handle to the event log to be cleared. The OpenEventLog + * function returns this handle. + * @param lpBackupFileName + * The absolute or relative path of the backup file. If this file + * already exists, the function fails. If the lpBackupFileName + * parameter is NULL, the event log is not backed up. + * @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. The ClearEventLog function can + * fail if the event log is empty or the backup file already exists. + */ + boolean ClearEventLog(HANDLE hEventLog, String lpBackupFileName); + + /** + * Saves the specified event log to a backup file. The function does not + * clear the event log. + * + * @param hEventLog + * A handle to the open event log. The OpenEventLog function + * returns this handle. + * @param lpBackupFileName + * The absolute or relative path of the backup file. + * @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. + */ + boolean BackupEventLog(HANDLE hEventLog, String lpBackupFileName); + + /** + * Opens a handle to a backup event log created by the BackupEventLog + * function. + * + * @param lpUNCServerName + * The Universal Naming Convention (UNC) name of the remote + * server on which this operation is to be performed. If this + * parameter is NULL, the local computer is used. + * @param lpFileName + * The full path of the backup file. + * @return If the function succeeds, the return value is a handle to the + * backup event log. If the function fails, the return value is + * NULL. To get extended error information, call GetLastError. + */ + HANDLE OpenBackupEventLog(String lpUNCServerName, String lpFileName); + + /** + * Reads the specified number of entries from the specified event log. The + * function can be used to read log entries in chronological or reverse + * chronological order. + * + * @param hEventLog + * A handle to the event log to be read. The OpenEventLog + * function returns this handle. + * @param dwReadFlags + * Use the following flag values to indicate how to read the log + * file. + * @param dwRecordOffset + * The record number of the log-entry at which the read operation + * should start. This parameter is ignored unless dwReadFlags + * includes the EVENTLOG_SEEK_READ flag. + * @param lpBuffer + * An application-allocated buffer that will receive one or more + * EVENTLOGRECORD structures. This parameter cannot be NULL, even + * if the nNumberOfBytesToRead parameter is zero. The maximum + * size of this buffer is 0x7ffff bytes. + * @param nNumberOfBytesToRead + * The size of the lpBuffer buffer, in bytes. This function will + * read as many log entries as will fit in the buffer; the + * function will not return partial entries. + * @param pnBytesRead + * A pointer to a variable that receives the number of bytes read + * by the function. + * @param pnMinNumberOfBytesNeeded + * A pointer to a variable that receives the required size of the + * lpBuffer buffer. This value is valid only this function + * returns zero and GetLastError returns + * ERROR_INSUFFICIENT_BUFFER. + * @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. + */ + boolean ReadEventLog(HANDLE hEventLog, int dwReadFlags, + int dwRecordOffset, Pointer lpBuffer, int nNumberOfBytesToRead, + IntByReference pnBytesRead, IntByReference pnMinNumberOfBytesNeeded); + + /** + * The GetOldestEventLogRecord function retrieves the absolute record number + * of the oldest record in the specified event log. + * + * @param hEventLog + * Handle to the open event log. This handle is returned by the + * OpenEventLog or OpenBackupEventLog function. + * @param OldestRecord + * Pointer to a variable that receives the absolute record number + * of the oldest record in the specified event log. + * @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. + */ + boolean GetOldestEventLogRecord(HANDLE hEventLog, IntByReference OldestRecord); + + /** + * Changes the optional configuration parameters of a service. + * + * @param hService + * A handle to the service. This handle is returned by the + * OpenService or CreateService function and must have the + * SERVICE_CHANGE_CONFIG access right. For more information, + * see Service Security and Access Rights. + * If the service controller handles the SC_ACTION_RESTART + * action, hService must have the SERVICE_START access right. + * @param dwInfoLevel + * The configuration information to be changed. + * @param lpInfo + * A pointer to the new value to be set for the configuration + * information. The format of this data depends on the value + * of the dwInfoLevel parameter. If this value is NULL, the + * information remains unchanged. + * @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. + */ + public boolean ChangeServiceConfig2(SC_HANDLE hService, int dwInfoLevel, + ChangeServiceConfig2Info lpInfo); + + /** + * Retrieves the optional configuration parameters of the specified service. + * + * @param hService + * A handle to the service. This handle is returned by the OpenService or + * CreateService function and must have the SERVICE_QUERY_CONFIG access right. For + * more information, see Service Security and Access Rights. + * @param dwInfoLevel + * The configuration information to be queried. + * @param lpBuffer + * A pointer to the buffer that receives the service configuration information. The + * format of this data depends on the value of the dwInfoLevel parameter. + * The maximum size of this array is 8K bytes. To determine the required size, + * specify NULL for this parameter and 0 for the cbBufSize parameter. The function + * fails and GetLastError returns ERROR_INSUFFICIENT_BUFFER. The pcbBytesNeeded + * parameter receives the needed size. + * @param cbBufSize + * The size of the structure pointed to by the lpBuffer parameter, in bytes. + * @param pcbBytesNeeded + * A pointer to a variable that receives the number of bytes required to store the + * configuration information, if the function fails with ERROR_INSUFFICIENT_BUFFER. + * @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. + */ + public boolean QueryServiceConfig2(SC_HANDLE hService, int dwInfoLevel, + Pointer lpBuffer, int cbBufSize, IntByReference pcbBytesNeeded); + + + /** + * Retrieves the current status of the specified service based on the + * specified information level. + * + * @param hService + * A handle to the service. This handle is returned by the + * OpenService(SC_HANDLE, String, int) or CreateService() + * function, and it must have the SERVICE_QUERY_STATUS access + * right. For more information, see Service Security and Access Rights. + * @param InfoLevel + * The service attributes to be returned (a value from + * SC_STATUS_TYPE enumeration). Use SC_STATUS_PROCESS_INFO to + * retrieve the service status information. The lpBuffer + * parameter is a pointer to a SERVICE_STATUS_PROCESS structure. + * Currently, no other information levels are defined. + * @param lpBuffer + * (optional) A pointer to the buffer that receives the status + * information. The format of this data depends on the value of + * the InfoLevel parameter. The maximum size of this array is 8K + * bytes. To determine the required size, specify NULL for this + * parameter and 0 for the cbBufSize parameter. The function will + * fail and GetLastError will return ERROR_INSUFFICIENT_BUFFER. + * The pcbBytesNeeded parameter will receive the required size. + * @param cbBufSize + * The size of the buffer pointed to by the lpBuffer parameter, + * in bytes. + * @param pcbBytesNeeded + * A pointer to a variable that receives the number of bytes + * needed to store all status information, if the function fails + * with ERROR_INSUFFICIENT_BUFFER. + * @return If the function succeeds, the return value is true. If the + * function fails, the return value is false. To get extended error + * information, call GetLastError. This value is a nonzero error + * code defined in Winerror.h. + */ + boolean QueryServiceStatusEx(SC_HANDLE hService, int InfoLevel, + SERVICE_STATUS_PROCESS lpBuffer, int cbBufSize, + IntByReference pcbBytesNeeded); + + /** + * Sends a control code to a service. To specify additional information when + * stopping a service, use the ControlServiceEx function. + * + * @param hService + * A handle to the service. This handle is returned by the + * OpenService(SC_HANDLE, String, int) or CreateService() + * function. The access rights required for this handle depend on + * the dwControl code requested. + * @param dwControl + * This parameter can be one of the following control codes + * (found in Winsvc.h): SERVICE_CONTROL_STOP, + * SERVICE_CONTROL_PAUSE, SERVICE_CONTROL_CONTINUE + * SERVICE_CONTROL_INTERROGATE, SERVICE_CONTROL_PARAMCHANGE, + * SERVICE_CONTROL_NETBINDADD, SERVICE_CONTROL_NETBINDREMOVE, + * SERVICE_CONTROL_NETBINDENABLE, SERVICE_CONTROL_NETBINDDISABLE + * This value can also be a user-defined control code, as + * described below: Range 128 to 255 - The service defines the + * action associated with the control code. The hService handle + * must have the SERVICE_USER_DEFINED_CONTROL access right. + * @param lpServiceStatus + * A pointer to a SERVICE_STATUS structure that receives the + * latest service status information. The information returned + * reflects the most recent status that the service reported to + * the service control manager. The service control manager fills + * in the structure only when ControlService returns one of the + * following error codes: NO_ERROR, + * ERROR_INVALID_SERVICE_CONTROL, + * ERROR_SERVICE_CANNOT_ACCEPT_CTRL, or ERROR_SERVICE_NOT_ACTIVE. + * Otherwise, the structure is not filled in. + * @return If the function succeeds, the return value is true. If the + * function fails, the return value is false. To get extended error + * information, call GetLastError. This value is a nonzero error + * code defined in Winerror.h. + */ + boolean ControlService(SC_HANDLE hService, int dwControl, SERVICE_STATUS lpServiceStatus); + + /** + * Starts a service. + * + * @param hService + * A handle to the service. This handle is returned by the + * OpenService(SC_HANDLE, String, int) or CreateService() + * function, and it must have the SERVICE_START access right. For + * more information, see + * Service Security and Access Rights. + * @param dwNumServiceArgs + * The number of strings in the lpServiceArgVectors array. If + * lpServiceArgVectors is NULL, this parameter can be zero. + * @param lpServiceArgVectors + * The null-terminated strings to be passed to the ServiceMain + * function for the service as arguments. If there are no + * arguments, this parameter can be null. Otherwise, the first + * argument (lpServiceArgVectors[0]) is the name of the service, + * followed by any additional arguments (lpServiceArgVectors[1] + * through lpServiceArgVectors[dwNumServiceArgs-1]). Driver + * services do not receive these arguments. + * @return If the function succeeds, the return value is true. If the + * function fails, the return value is false. To get extended error + * information, call GetLastError. This value is a nonzero error + * code defined in Winerror.h. + */ + boolean StartService(SC_HANDLE hService, int dwNumServiceArgs, String[] lpServiceArgVectors); + + /** + * Closes a handle to a service control manager or service object. + * + * @param hSCObject + * A handle to the service control manager object or the service + * object to close. Handles to service control manager objects + * are returned by the OpenSCManager(String, String, int) + * function, and handles to service objects are returned by + * either the OpenService(SC_HANDLE, String, int) or + * CreateService() 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. This value is a nonzero error + * code defined in Winerror.h. + */ + boolean CloseServiceHandle(SC_HANDLE hSCObject); + + /** + * Opens an existing service. + * + * @param hSCManager + * A handle to the service control manager database. The + * OpenSCManager(String, String, int) function returns this + * handle. + * @param lpServiceName + * The name of the service to be opened. This is the name + * specified by the lpServiceName parameter of the CreateService + * function when the service object was created, not the service + * display name that is shown by user interface applications to + * identify the service. The maximum string length is 256 + * characters. The service control manager database preserves the + * case of the characters, but service name comparisons are + * always case insensitive. Forward-slash (/) and backslash (\) + * are invalid service name characters. + * @param dwDesiredAccess + * The access to the service. For a list of access rights, see + * Service Security and Access Rights. Before granting the + * requested access, the system checks the access token of the + * calling process against the discretionary access-control list + * of the security descriptor associated with the service object. + * @return If the function succeeds, the return value is a handle to the + * service. If the function fails, the return value is NULL. To get + * extended error information, call GetLastError. This value is a + * nonzero error code defined in Winerror.h. + */ + SC_HANDLE OpenService(SC_HANDLE hSCManager, String lpServiceName, int dwDesiredAccess); + + /** + * Establishes a connection to the service control manager on the specified + * computer and opens the specified service control manager database. + * + * @param lpMachineName + * The name of the target computer. If the pointer is NULL or + * points to an empty string, the function connects to the + * service control manager on the local computer. + * @param lpDatabaseName + * The name of the service control manager database. This + * parameter should be set to SERVICES_ACTIVE_DATABASE. If it is + * NULL, the SERVICES_ACTIVE_DATABASE database is opened by + * default. + * @param dwDesiredAccess + * The access to the service control manager. For a list of + * access rights, see + * Service Security and Access Rights. Before granting the + * requested access rights, the system checks the access token of + * the calling process against the discretionary access-control + * list of the security descriptor associated with the service + * control manager. The SC_MANAGER_CONNECT access right is + * implicitly specified by calling this function. + * @return If the function succeeds, the return value is a handle to the + * specified service control manager database. If the function + * fails, the return value is NULL. To get extended error + * information, call GetLastError. This value is a nonzero error + * code defined in Winerror.h. + */ + SC_HANDLE OpenSCManager(String lpMachineName, String lpDatabaseName, int dwDesiredAccess); + + /** + * Creates a new process and its primary thread. The new process runs in the + * security context of the user represented by the specified token. + * + * Typically, the process that calls the CreateProcessAsUser function must + * have the SE_INCREASE_QUOTA_NAME privilege and may require the + * SE_ASSIGNPRIMARYTOKEN_NAME privilege if the token is not assignable. If + * this function fails with ERROR_PRIVILEGE_NOT_HELD (1314), use the + * CreateProcessWithLogonW function instead. CreateProcessWithLogonW + * requires no special privileges, but the specified user account must be + * allowed to log on interactively. Generally, it is best to use + * CreateProcessWithLogonW to create a process with alternate credentials. + * + * @param hToken + * A handle to the primary token that represents a user. + * @param lpApplicationName + * The name of the module to be executed. + * @param lpCommandLine + * The command line to be executed. + * @param lpProcessAttributes + * A pointer to a SECURITY_ATTRIBUTES structure that specifies a + * security descriptor for the new process object and determines + * whether child processes can inherit the returned handle to the + * process. + * @param lpThreadAttributes + * A pointer to a SECURITY_ATTRIBUTES structure that specifies a + * security descriptor for the new thread object and determines + * whether child processes can inherit the returned handle to the + * thread. + * @param bInheritHandles + * If this parameter is TRUE, each inheritable handle in the + * calling process is inherited by the new process. If the + * parameter is FALSE, the handles are not inherited. Note that + * inherited handles have the same value and access rights as the + * original handles. + * @param dwCreationFlags + * The flags that control the priority class and the creation of + * the process. For a list of values, see Process Creation Flags. + * @param lpEnvironment + * A pointer to an environment block for the new process. If this + * parameter is NULL, the new process uses the environment of the + * calling process. + * + * An environment block consists of a null-terminated block of + * null-terminated strings. Each string is in the following form: + * name=value\0 + * @param lpCurrentDirectory + * The full path to the current directory for the process. The + * string can also specify a UNC path. + * @param lpStartupInfo + * A pointer to a STARTUPINFO or STARTUPINFOEX structure. + * @param lpProcessInformation + * A pointer to a PROCESS_INFORMATION structure that receives + * identification information about the new process. + * @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. + */ + boolean CreateProcessAsUser(HANDLE hToken, String lpApplicationName, + String lpCommandLine, SECURITY_ATTRIBUTES lpProcessAttributes, + SECURITY_ATTRIBUTES lpThreadAttributes, boolean bInheritHandles, + int dwCreationFlags, String lpEnvironment, + String lpCurrentDirectory, WinBase.STARTUPINFO lpStartupInfo, + WinBase.PROCESS_INFORMATION lpProcessInformation); + + /** + * The AdjustTokenPrivileges function enables or disables privileges in the + * specified access token. Enabling or disabling privileges in an access + * token requires TOKEN_ADJUST_PRIVILEGES access. + * + * @param TokenHandle + * A handle to the access token that contains the privileges to + * be modified. + * @param DisableAllPrivileges + * Specifies whether the function disables all of the token's + * privileges. + * @param NewState + * A pointer to a TOKEN_PRIVILEGES structure that specifies an + * array of privileges and their attributes. + * @param BufferLength + * Specifies the size, in bytes, of the buffer pointed to by the + * PreviousState parameter. This parameter can be zero if the + * PreviousState parameter is NULL. + * @param PreviousState + * A pointer to a buffer that the function fills with a + * TOKEN_PRIVILEGES structure that contains the previous state of + * any privileges that the function modifies. + * @param ReturnLength + * A pointer to a variable that receives the required size, in + * bytes, of the buffer pointed to by the PreviousState + * parameter. + * @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. + */ + boolean AdjustTokenPrivileges(HANDLE TokenHandle, + boolean DisableAllPrivileges, WinNT.TOKEN_PRIVILEGES NewState, + int BufferLength, WinNT.TOKEN_PRIVILEGES PreviousState, + IntByReference ReturnLength); + + /** + * The LookupPrivilegeName function retrieves the name that corresponds to + * the privilege represented on a specific system by a specified locally + * unique identifier (LUID). + * + * @param lpSystemName + * A pointer to a null-terminated string that specifies the name + * of the system on which the privilege name is retrieved. If a + * null string is specified, the function attempts to find the + * privilege name on the local system. + * @param lpLuid + * A pointer to the LUID by which the privilege is known on the + * target system. + * @param lpName + * A pointer to a buffer that receives a null-terminated string + * that represents the privilege name. For example, this string + * could be "SeSecurityPrivilege". + * @param cchName + * A pointer to a variable that specifies the size, in a TCHAR + * value, of the lpName buffer. + * @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. + */ + boolean LookupPrivilegeName(String lpSystemName, WinNT.LUID lpLuid, + char[] lpName, IntByReference cchName); + + /** + * The LookupPrivilegeValue function retrieves the locally unique identifier + * (LUID) used on a specified system to locally represent the specified + * privilege name. + * + * @param lpSystemName + * A pointer to a null-terminated string that specifies the name + * of the system on which the privilege name is retrieved. If a + * null string is specified, the function attempts to find the + * privilege name on the local system. + * @param lpName + * A pointer to a null-terminated string that specifies the name + * of the privilege, as defined in the Winnt.h header file. For + * example, this parameter could specify the constant, + * SE_SECURITY_NAME, or its corresponding string, + * "SeSecurityPrivilege". + * @param lpLuid + * A pointer to a variable that receives the LUID by which the + * privilege is known on the system specified by the lpSystemName + * parameter. + * @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. + */ + boolean LookupPrivilegeValue(String lpSystemName, String lpName, WinNT.LUID lpLuid); + + /** + * The function obtains specified information about the security of a file + * or directory. The information obtained is constrained by the caller's + * access rights and privileges. + * + * @param lpFileName + * A pointer to a null-terminated string that specifies the file + * or directory for which security information is retrieved. + * @param RequestedInformation + * A SECURITY_INFORMATION value that identifies the security + * information being requested. See WinNT *_SECURITY_INFORMATION + * @param pointer + * A pointer to a buffer that receives a copy of the security + * descriptor of the object specified by the lpFileName + * parameter. The calling process must have permission to view + * the specified aspects of the object's security status. The + * SECURITY_DESCRIPTOR structure is returned in self-relative + * format. + * @param nLength + * Specifies the size, in bytes, of the buffer pointed to by the + * pSecurityDescriptor parameter. + * @param lpnLengthNeeded + * A pointer to the variable that receives the number of bytes + * necessary to store the complete security descriptor. If the + * returned number of bytes is less than or equal to nLength, the + * entire security descriptor is returned in the output buffer; + * otherwise, none of the descriptor is returned. + * @return whether the call succeeded + */ + boolean GetFileSecurity(String lpFileName, + int RequestedInformation, Pointer pointer, int nLength, + IntByReference lpnLengthNeeded); + + /** + * The SetFileSecurity function sets the security of a file or directory object. + * This function is obsolete. Use the SetNamedSecurityInfo function instead. + * + * @param lpFileName + * A pointer to a null-terminated string that specifies the file or directory for which security is set. + * Note that security applied to a directory is not inherited by its children. + * @param SecurityInformation + * Specifies a SECURITY_INFORMATION structure that identifies the contents of the security descriptor + * pointed to by the pSecurityDescriptor parameter. + * @param pSecurityDescriptor + * A pointer to a SECURITY_DESCRIPTOR structure. + * @return + * If the function succeeds, the function returns nonzero. If the function fails, it returns zero. To get + * extended error information, call GetLastError. + */ + boolean SetFileSecurity(String lpFileName, int SecurityInformation, Pointer pSecurityDescriptor); + + /** + * The GetSecurityInfo function retrieves a copy of the security descriptor for an object specified by a handle. + * + * @param handle [in] + * A handle to the object from which to retrieve security information. + * @param ObjectType [in] + * SE_OBJECT_TYPE enumeration value that indicates the type of object. + * @param SecurityInfo [in] + * A set of bit flags that indicate the type of security information to retrieve. See WinNT *_SECURITY_INFORMATION + * @param ppsidOwner [out, optional] + * A pointer to a variable that receives a pointer to the owner SID in the security descriptor returned + * in ppSecurityDescriptor. The returned pointer is valid only if you set the OWNER_SECURITY_INFORMATION flag. + * This parameter can be NULL if you do not need the owner SID. + * @param ppsidGroup [in, optional] + * A pointer to a variable that receives a pointer to the primary group SID in the returned security descriptor. + * The returned pointer is valid only if you set the GROUP_SECURITY_INFORMATION flag. This parameter can be NULL + * if you do not need the group SID. + * @param ppDacl [in, optional] + * A pointer to a variable that receives a pointer to the DACL in the returned security descriptor. The returned + * pointer is valid only if you set the DACL_SECURITY_INFORMATION flag. This parameter can be NULL if you do not + * need the DACL. + * @param ppSacl [in, optional] + * A pointer to a variable that receives a pointer to the SACL in the returned security descriptor. The returned + * pointer is valid only if you set the SACL_SECURITY_INFORMATION flag. This parameter can be NULL if you do not + * need the SACL. + * @param ppSecurityDescriptor + * A pointer to a variable that receives a pointer to the security descriptor of the object. When you have finished + * using the pointer, free the returned buffer by calling the LocalFree function. + * This parameter is required if any one of the ppsidOwner, ppsidGroup, ppDacl, or ppSacl parameters is not NULL. + * @return whether the call succeeded. A nonzero return is a failure. + * + *

    NOTES:

    + *

    1. If the ppsidOwner, ppsidGroup, ppDacl, and ppSacl parameters are non-NULL, and the SecurityInfo parameter specifies + * that they be retrieved from the object, those parameters will point to the corresponding parameters in the security descriptor + * returned in ppSecurityDescriptor.

    + *

    2. To read the owner, group, or DACL from the object's security descriptor, the calling process must have been granted + * READ_CONTROL access when the handle was opened. To get READ_CONTROL access, the caller must be the owner of the object or + * the object's DACL must grant the access.

    + *

    3. To read the SACL from the security descriptor, the calling process must have been granted ACCESS_SYSTEM_SECURITY access + * when the handle was opened. The proper way to get this access is to enable the SE_SECURITY_NAME privilege in the caller's + * current token, open the handle for ACCESS_SYSTEM_SECURITY access, and then disable the privilege.

    + *

    4. If the supplied handle was opened with an ACCESS_MASK value of MAXIMUM_ALLOWED, + * then the SetSecurityInfo function will not propagate ACEs to children.

    + */ + int GetSecurityInfo(HANDLE handle, + int ObjectType, + int SecurityInfo, + PointerByReference ppsidOwner, + PointerByReference ppsidGroup, + PointerByReference ppDacl, + PointerByReference ppSacl, + PointerByReference ppSecurityDescriptor); + + /** + * The SetSecurityInfo function sets specified security information in + * the security descriptor of a specified object. The caller identifies the + * object by a handle. + * + * @param handle [in] + * A handle to the object for which to set security information. + * @param ObjectType [in] + * A value of the SE_OBJECT_TYPE enumeration that indicates the type + * of object named by the pObjectName parameter. + * @param SecurityInfo [in] + * A set of bit flags that indicate the type of security + * information to set. See WinNT *_SECURITY_INFORMATION + * @param ppsidOwner [in, optional] + * A pointer to a SID structure that identifies the owner of the object. + * If the caller does not have the SeRestorePrivilege constant + * (see Privilege Constants), this SID must be contained in the + * caller's token, and must have the SE_GROUP_OWNER permission enabled. + * The SecurityInfo parameter must include the OWNER_SECURITY_INFORMATION + * flag. To set the owner, the caller must have WRITE_OWNER access to + * the object or have the SE_TAKE_OWNERSHIP_NAME privilege enabled. + * If you are not setting the owner SID, this parameter can be NULL. + * @param ppsidGroup [in, optional] + * A pointer to a SID that identifies the primary group of the object. + * The SecurityInfo parameter must include the GROUP_SECURITY_INFORMATION + * flag. If you are not setting the primary group SID, this parameter + * can be NULL. + * @param ppDacl [in, optional] + * A pointer to the new DACL for the object. The SecurityInfo parameter + * must include the DACL_SECURITY_INFORMATION flag. The caller must have + * WRITE_DAC access to the object or be the owner of the object. If you + * are not setting the DACL, this parameter can be NULL. + * @param ppSacl [in, optional] + * A pointer to the new SACL for the object. The SecurityInfo parameter + * must include any of the following flags: SACL_SECURITY_INFORMATION, + * LABEL_SECURITY_INFORMATION, ATTRIBUTE_SECURITY_INFORMATION, + * SCOPE_SECURITY_INFORMATION, or BACKUP_SECURITY_INFORMATION. + * If setting SACL_SECURITY_INFORMATION or SCOPE_SECURITY_INFORMATION, + * the caller must have the SE_SECURITY_NAME privilege enabled. If + * you are not setting the SACL, this parameter can be NULL. + * @return whether the call succeeded. A nonzero return is a failure. + * + *

    NOTES:

    + *

    1. If you are setting the discretionary access control list (DACL) or any elements + * in the system access control list (SACL) of an object, the system automatically + * propagates any inheritable access control entries (ACEs) to existing child objects, + * according to the ACE inheritance rules.

    + *

    2. The SetSecurityInfo function does not reorder access-allowed or access-denied + * ACEs based on the preferred order. When propagating inheritable ACEs to existing + * child objects, SetSecurityInfo puts inherited ACEs in order after all of the + * noninherited ACEs in the DACLs of the child objects.

    + *

    3. If share access to the children of the object is not available, this function + * will not propagate unprotected ACEs to the children. For example, if a directory + * is opened with exclusive access, the operating system will not propagate unprotected + * ACEs to the subdirectories or files of that directory when the security on the + * directory is changed.

    + *

    4. If the supplied handle was opened with an ACCESS_MASK value of MAXIMUM_ALLOWED, + * then the SetSecurityInfo function will not propagate ACEs to children.

    + */ + int SetSecurityInfo(HANDLE handle, + int ObjectType, + int SecurityInfo, + Pointer ppsidOwner, + Pointer ppsidGroup, + Pointer ppDacl, + Pointer ppSacl); + + /** + * The GetNamedSecurityInfo function retrieves a copy of the security + * descriptor for an object specified by name + * + * @param pObjectName + * A pointer to a that specifies the name of the object from + * which to retrieve security information. + * For descriptions of the string formats for the different + * object types, see SE_OBJECT_TYPE. + * @param ObjectType + * Specifies a value from the SE_OBJECT_TYPE enumeration that + * indicates the type of object named by the pObjectName parameter. + * @param SecurityInfo + * A set of bit flags that indicate the type of security + * information to retrieve. See WinNT *_SECURITY_INFORMATION + * @param ppsidOwner [out, optional] + * A pointer to a variable that receives a pointer to the owner SID + * in the security descriptor returned in ppSecurityDescriptor + * or NULL if the security descriptor has no owner SID. + * The returned pointer is valid only if you set the + * OWNER_SECURITY_INFORMATION flag. Also, this parameter can be + * NULL if you do not need the owner SID. + * @param ppsidGroup [out, optional] + * A pointer to a variable that receives a pointer to the primary + * group SID in the returned security descriptor or NULL if the + * security descriptor has no group SID. The returned pointer is + * valid only if you set the GROUP_SECURITY_INFORMATION flag. + * Also, this parameter can be NULL if you do not need the group SID. + * @param ppDacl [out, optional] + * A pointer to a variable that receives a pointer to the DACL in + * the returned security descriptor or NULL if the security + * descriptor has no DACL. The returned pointer is valid only if + * you set the DACL_SECURITY_INFORMATION flag. Also, this parameter + * can be NULL if you do not need the DACL. + * @param ppSacl [out, optional] + * A pointer to a variable that receives a pointer to the SACL in + * the returned security descriptor or NULL if the security + * descriptor has no SACL. The returned pointer is valid only if + * you set the SACL_SECURITY_INFORMATION flag. Also, this parameter + * can be NULL if you do not need the SACL. + * @param ppSecurityDescriptor + * A pointer to a variable that receives a pointer to the security + * descriptor of the object. When you have finished using the + * pointer, free the returned buffer by calling the LocalFree + * function. + * + * This parameter is required if any one of the ppsidOwner, + * ppsidGroup, ppDacl, or ppSacl parameters is not NULL. + * @return whether the call succeeded. A nonzero return is a failure. + * + * NOTES: + * 1. To read the owner, group, or DACL from the object's security descriptor, + * the object's DACL must grant READ_CONTROL access to the caller, or the caller + * must be the owner of the object. + * 2. To read the system access control list of the object, the SE_SECURITY_NAME + * privilege must be enabled for the calling process. For information about the + * security implications of enabling privileges, see Running with Special Privileges. + */ + int GetNamedSecurityInfo( + String pObjectName, + int ObjectType, + int SecurityInfo, + PointerByReference ppsidOwner, + PointerByReference ppsidGroup, + PointerByReference ppDacl, + PointerByReference ppSacl, + PointerByReference ppSecurityDescriptor); + + /** + * The SetNamedSecurityInfo function sets specified security information in + * the security descriptor of a specified object. The caller identifies the + * object by name. + * + * @param pObjectName [in] + * A pointer to a string that specifies the name of the object for + * which to set security information. This can be + * the name of a local or remote file or directory on an NTFS file + * system, network share, registry key, semaphore, event, mutex, + * file mapping, or waitable timer. * + * For descriptions of the string formats for the different + * object types, see SE_OBJECT_TYPE. + * @param ObjectType [in] + * A value of the SE_OBJECT_TYPE enumeration that indicates the type + * of object named by the pObjectName parameter. + * @param SecurityInfo [in] + * A set of bit flags that indicate the type of security + * information to set. See WinNT *_SECURITY_INFORMATION + * @param ppsidOwner [in, optional] + * A pointer to a SID structure that identifies the owner of the object. + * If the caller does not have the SeRestorePrivilege constant + * (see Privilege Constants), this SID must be contained in the + * caller's token, and must have the SE_GROUP_OWNER permission enabled. + * The SecurityInfo parameter must include the OWNER_SECURITY_INFORMATION + * flag. To set the owner, the caller must have WRITE_OWNER access to + * the object or have the SE_TAKE_OWNERSHIP_NAME privilege enabled. + * If you are not setting the owner SID, this parameter can be NULL. + * @param ppsidGroup [in, optional] + * A pointer to a SID that identifies the primary group of the object. + * The SecurityInfo parameter must include the GROUP_SECURITY_INFORMATION + * flag. If you are not setting the primary group SID, this parameter + * can be NULL. + * @param ppDacl [in, optional] + * A pointer to the new DACL for the object. The SecurityInfo parameter + * must include the DACL_SECURITY_INFORMATION flag. The caller must have + * WRITE_DAC access to the object or be the owner of the object. If you + * are not setting the DACL, this parameter can be NULL. + * @param ppSacl [in, optional] + * A pointer to the new SACL for the object. The SecurityInfo parameter + * must include any of the following flags: SACL_SECURITY_INFORMATION, + * LABEL_SECURITY_INFORMATION, ATTRIBUTE_SECURITY_INFORMATION, + * SCOPE_SECURITY_INFORMATION, or BACKUP_SECURITY_INFORMATION. + * If setting SACL_SECURITY_INFORMATION or SCOPE_SECURITY_INFORMATION, + * the caller must have the SE_SECURITY_NAME privilege enabled. If + * you are not setting the SACL, this parameter can be NULL. + * @return whether the call succeeded. A nonzero return is a failure. + * + * NOTES: + * 1. The SetNamedSecurityInfo function does not reorder access-allowed or access-denied + * ACEs based on the preferred order. When propagating inheritable ACEs to existing + * child objects, SetNamedSecurityInfo puts inherited ACEs in order after all of the + * noninherited ACEs in the DACLs of the child objects. + * 2. This function transfers information in plaintext. The information transferred by + * this function is signed unless signing has been turned off for the system, but no + * encryption is performed. + * 3. When you update access rights of a folder indicated by an UNC path, for example + * \\Test\TestFolder, the original inherited ACE is removed and the full volume path + * is not included. + */ + int SetNamedSecurityInfo( + String pObjectName, + int ObjectType, + int SecurityInfo, + Pointer ppsidOwner, + Pointer ppsidGroup, + Pointer ppDacl, + Pointer ppSacl); + + /** + * The GetSecurityDescriptorLength function returns the length, in bytes, of a structurally + * valid security descriptor. The length includes the length of all associated structures. + * + * @param ppSecurityDescriptor + * A pointer to the SECURITY_DESCRIPTOR structure whose length the function returns. + * The pointer is assumed to be valid. + * @return If the function succeeds, the function returns the length, in bytes, of the SECURITY_DESCRIPTOR structure. * If the SECURITY_DESCRIPTOR structure is not valid, the return value is undefined. - */ - public int GetSecurityDescriptorLength(Pointer ppSecurityDescriptor); - - /** - * The IsValidSecurityDescriptor function determines whether the components of a security descriptor are valid. - * - * @param ppSecurityDescriptor [in] + */ + int GetSecurityDescriptorLength(Pointer ppSecurityDescriptor); + + /** + * The IsValidSecurityDescriptor function determines whether the components of a security descriptor are valid. + * + * @param ppSecurityDescriptor [in] * A pointer to a SECURITY_DESCRIPTOR structure that the function validates. - * @return If the components of the security descriptor are valid, the return value is nonzero. - */ - public boolean IsValidSecurityDescriptor(Pointer ppSecurityDescriptor); - - /** - * The IsValidAcl function validates an access control list (ACL). - * - * @param pAcl [in] + * @return If the components of the security descriptor are valid, the return value is nonzero. + */ + boolean IsValidSecurityDescriptor(Pointer ppSecurityDescriptor); + + /** + * A pointer to a SECURITY_DESCRIPTOR structure in absolute format. The function creates a version of this security + * descriptor in self-relative format without modifying the original. + * @param pAbsoluteSD + * A pointer to a SECURITY_DESCRIPTOR structure in absolute format. The function creates a version of this + * security descriptor in self-relative format without modifying the original. + * @param pSelfRelativeSD + * A pointer to a buffer the function fills with a security descriptor in self-relative format. + * @param lpdwBufferLength + * A pointer to a variable specifying the size of the buffer pointed to by the pSelfRelativeSD parameter. + * If the buffer is not large enough for the security descriptor, the function fails and sets this variable + * to the minimum required size. + * @return If the function succeeds, the function returns nonzero. If the function fails, it returns zero. To get + * extended error information, call GetLastError. Possible return codes include, but are not limited to, the following: + * ERROR_INSUFFICIENT_BUFFER - One or more of the buffers is too small. + */ + boolean MakeSelfRelativeSD(SECURITY_DESCRIPTOR pAbsoluteSD, + SECURITY_DESCRIPTOR_RELATIVE pSelfRelativeSD, + IntByReference lpdwBufferLength); + + /** + * The MakeAbsoluteSD function creates a security descriptor in absolute format by using a + * security descriptor in self-relative format as a template. + * @param pSelfRelativeSD + * A pointer to a SECURITY_DESCRIPTOR structure in self-relative format. The function creates an + * absolute-format version of this security descriptor without modifying the original security descriptor. + * @param pAbsoluteSD + * A pointer to a buffer that the function fills with the main body of an absolute-format security + * descriptor. This information is formatted as a SECURITY_DESCRIPTOR structure. + * @param lpdwAbsoluteSDSize + * A pointer to a variable that specifies the size of the buffer pointed to by the pAbsoluteSD parameter. + * If the buffer is not large enough for the security descriptor, the function fails and sets this variable + * to the minimum required size. + * @param pDacl + * A pointer to a buffer the function fills with the discretionary access control list (DACL) of the + * absolute-format security descriptor. The main body of the absolute-format security descriptor references + * this pointer. + * @param lpdwDaclSize + * A pointer to a variable that specifies the size of the buffer pointed to by the pDacl parameter. If + * the buffer is not large enough for the access control list (ACL), the function fails and sets this + * variable to the minimum required size. + * @param pSacl + * A pointer to a buffer the function fills with the system access control list (SACL) of the absolute-format + * security descriptor. The main body of the absolute-format security descriptor references this pointer. + * @param lpdwSaclSize + * A pointer to a variable that specifies the size of the buffer pointed to by the pSacl parameter. If the + * buffer is not large enough for the ACL, the function fails and sets this variable to the minimum required + * size. + * @param pOwner + * A pointer to a buffer the function fills with the security identifier (SID) of the owner of the + * absolute-format security descriptor. The main body of the absolute-format security descriptor references + * this pointer. + * @param lpdwOwnerSize + * A pointer to a variable that specifies the size of the buffer pointed to by the pOwner parameter. + * If the buffer is not large enough for the SID, the function fails and sets this variable to the minimum + * required size. + * @param pPrimaryGroup + * A pointer to a buffer the function fills with the SID of the absolute-format security descriptor's + * primary group. The main body of the absolute-format security descriptor references this pointer. + * @param lpdwPrimaryGroupSize + * A pointer to a variable that specifies the size of the buffer pointed to by the pPrimaryGroup parameter. + * If the buffer is not large enough for the SID, the function fails and sets this variable to the minimum + * required size. + * @return If the function succeeds, the function returns nonzero. If the function fails, it returns zero. To get + * extended error information, call GetLastError. Possible return codes include, but are not limited to, the following: + * ERROR_INSUFFICIENT_BUFFER - One or more of the buffers is too small. + */ + boolean MakeAbsoluteSD(SECURITY_DESCRIPTOR_RELATIVE pSelfRelativeSD, + SECURITY_DESCRIPTOR pAbsoluteSD, + IntByReference lpdwAbsoluteSDSize, + ACL pDacl, + IntByReference lpdwDaclSize, + ACL pSacl, + IntByReference lpdwSaclSize, + PSID pOwner, + IntByReference lpdwOwnerSize, + PSID pPrimaryGroup, + IntByReference lpdwPrimaryGroupSize); + + /** + * The IsValidAcl function validates an access control list (ACL). + * + * @param pAcl [in] * A pointer to an ACL structure validated by this function. This value must not be NULL. - * @return If the ACL is valid, the function returns nonzero. If the ACL is not valid, the function returns zero. - * There is no extended error information for this function; do not call GetLastError. - * - * This function checks the revision level of the ACL and verifies that the number of access control entries - * (ACEs) specified in the AceCount member of the ACL structure fits the space specified by the AclSize member - * of the ACL structure.If pAcl is NULL, the application will fail with an access violation. - */ - public boolean IsValidAcl(Pointer pAcl); + * @return If the ACL is valid, the function returns nonzero. If the ACL is not valid, the function returns zero. + * There is no extended error information for this function; do not call GetLastError. + * + * This function checks the revision level of the ACL and verifies that the number of access control entries + * (ACEs) specified in the AceCount member of the ACL structure fits the space specified by the AclSize member + * of the ACL structure.If pAcl is NULL, the application will fail with an access violation. + */ + boolean IsValidAcl(Pointer pAcl); /** * Applies the given mapping of generic access rights to the given access mask. * @param AccessMask [in, out] A pointer to an access mask. * @param GenericMapping [in] A pointer to a GENERIC_MAPPING structure specifying a mapping of generic access types to specific and standard access types. */ - public void MapGenericMask(DWORDByReference AccessMask, GENERIC_MAPPING GenericMapping); + void MapGenericMask(DWORDByReference AccessMask, GENERIC_MAPPING GenericMapping); /** @@ -1747,159 +2361,465 @@ * @param AccessStatus [out] A pointer to a variable that receives the results of the access check. If the security descriptor allows the requested access rights to the client identified by the access token, AccessStatus is set to TRUE. Otherwise, AccessStatus is set to FALSE, and you can call GetLastError to get extended error information. * @return true on success; false on failure (use GetLastError to get extended error information) */ - public boolean AccessCheck(Pointer pSecurityDescriptor, - HANDLE ClientToken, DWORD DesiredAccess, - GENERIC_MAPPING GenericMapping, - PRIVILEGE_SET PrivilegeSet, - DWORDByReference PrivilegeSetLength, - DWORDByReference GrantedAccess, BOOLByReference AccessStatus); - - /** - * Encrypts a file or directory. All data streams in a file are encrypted. All - * new files created in an encrypted directory are encrypted. - * - * @param lpFileName - * The name of the file or directory to be encrypted. - * @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. - */ - public boolean EncryptFile(WString lpFileName); - - /** - * Decrypts an encrypted file or directory. - * - * @param lpFileName - * The name of the file or directory to be decrypted. - * @param dwReserved - * Reserved; must be zero. - * @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. - */ - public boolean DecryptFile(WString lpFileName, DWORD dwReserved); - - /** - * Retrieves the encryption status of the specified file. - * - * @param lpFileName - * The name of the file. - * @param lpStatus - * A pointer to a variable that receives the encryption status of the - * file. - * @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. - */ - public boolean FileEncryptionStatus(WString lpFileName, DWORDByReference lpStatus); - - /** - * Disables or enables encryption of the specified directory and the files in - * it. It does not affect encryption of subdirectories below the indicated - * directory. - * - * @param DirPath - * The name of the directory for which to enable or disable - * encryption. - * @param Disable - * Indicates whether to disable encryption (TRUE) or enable it - * (FALSE). - * @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. - */ - public boolean EncryptionDisable(WString DirPath, boolean Disable); - - /** - * Opens an encrypted file in order to backup (export) or restore (import) the - * file. This is one of a group of Encrypted File System (EFS) functions that - * is intended to implement backup and restore functionality, while - * maintaining files in their encrypted state. - * - * @param lpFileName - * The name of the file to be opened. The string must consist of - * characters from the Windows character set. - * @param ulFlags - * The operation to be performed. - * @param pvContext - * The address of a context block that must be presented in subsequent - * calls to ReadEncryptedFileRaw, WriteEncryptedFileRaw, or - * CloseEncryptedFileRaw. Do not modify it. - * @return If the function succeeds, it returns ERROR_SUCCESS. If the function - * fails, it returns a nonzero error code defined in WinError.h. You can use - * FormatMessage with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic - * text description of the error. - */ - public int OpenEncryptedFileRaw(WString lpFileName, ULONG ulFlags, - PointerByReference pvContext); - - /** - * Backs up (export) encrypted files. This is one of a group of Encrypted File - * System (EFS) functions that is intended to implement backup and restore - * functionality, while maintaining files in their encrypted state. - * - * @param pfExportCallback - * A pointer to the export callback function. The system calls the - * callback function multiple times, each time passing a block of the - * file's data to the callback function until the entire file has been - * read. For more information, see ExportCallback. - * @param pvCallbackContext - * A pointer to an application-defined and allocated context block. - * The system passes this pointer to the callback function as a - * parameter so that the callback function can have access to - * application-specific data. This can be a structure and can contain - * any data the application needs, such as the handle to the file that - * will contain the backup copy of the encrypted file. - * @param pvContext - * A pointer to a system-defined context block. The context block is - * returned by the OpenEncryptedFileRaw function. Do not modify it. - * @return If the function succeeds, the return value is ERROR_SUCCESS. If the - * function fails, it returns a nonzero error code defined in WinError.h. You - * can use FormatMessage with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a - * generic text description of the error. - */ - public int ReadEncryptedFileRaw(FE_EXPORT_FUNC pfExportCallback, - Pointer pvCallbackContext, Pointer pvContext); - - /** - * Restores (import) encrypted files. This is one of a group of Encrypted File - * System (EFS) functions that is intended to implement backup and restore - * functionality, while maintaining files in. - * - * @param pfImportCallback - * A pointer to the import callback function. The system calls the - * callback function multiple times, each time passing a buffer that - * will be filled by the callback function with a portion of backed-up - * file's data. When the callback function signals that the entire - * file has been processed, it tells the system that the restore - * operation is finished. For more information, see ImportCallback. - * @param pvCallbackContext - * A pointer to an application-defined and allocated context block. - * The system passes this pointer to the callback function as a - * parameter so that the callback function can have access to - * application-specific data. This can be a structure and can contain - * any data the application needs, such as the handle to the file that - * will contain the backup copy of the encrypted file. - * @param pvContext - * A pointer to a system-defined context block. The context block is - * returned by the OpenEncryptedFileRaw function. Do not modify it. - * @return If the function succeeds, the return value is ERROR_SUCCESS. If the - * function fails, it returns a nonzero error code defined in WinError.h. You - * can use FormatMessage with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a - * generic text description of the error. - */ - public int WriteEncryptedFileRaw(FE_IMPORT_FUNC pfImportCallback, - Pointer pvCallbackContext, Pointer pvContext); - - /** - * Closes an encrypted file after a backup or restore operation, and frees - * associated system resources. This is one of a group of Encrypted File - * System (EFS) functions that is intended to implement backup and restore - * functionality, while maintaining files in their encrypted state. - * - * @param pvContext - * A pointer to a system-defined context block. The - * OpenEncryptedFileRaw function returns the context block. - */ - public void CloseEncryptedFileRaw(Pointer pvContext); + boolean AccessCheck(Pointer pSecurityDescriptor, + HANDLE ClientToken, DWORD DesiredAccess, + GENERIC_MAPPING GenericMapping, + PRIVILEGE_SET PrivilegeSet, + DWORDByReference PrivilegeSetLength, + DWORDByReference GrantedAccess, BOOLByReference AccessStatus); + + /** + * Encrypts a file or directory. All data streams in a file are encrypted. All + * new files created in an encrypted directory are encrypted. + * + * @param lpFileName + * The name of the file or directory to be encrypted. + * @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. + */ + boolean EncryptFile(String lpFileName); + + /** + * Decrypts an encrypted file or directory. + * + * @param lpFileName + * The name of the file or directory to be decrypted. + * @param dwReserved + * Reserved; must be zero. + * @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. + */ + boolean DecryptFile(String lpFileName, DWORD dwReserved); + + /** + * Retrieves the encryption status of the specified file. + * + * @param lpFileName + * The name of the file. + * @param lpStatus + * A pointer to a variable that receives the encryption status of the + * file. + * @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. + */ + boolean FileEncryptionStatus(String lpFileName, DWORDByReference lpStatus); + + /** + * Disables or enables encryption of the specified directory and the files in + * it. It does not affect encryption of subdirectories below the indicated + * directory. + * + * @param DirPath + * The name of the directory for which to enable or disable + * encryption. + * @param Disable + * Indicates whether to disable encryption (TRUE) or enable it + * (FALSE). + * @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. + */ + boolean EncryptionDisable(String DirPath, boolean Disable); + + /** + * Opens an encrypted file in order to backup (export) or restore (import) the + * file. This is one of a group of Encrypted File System (EFS) functions that + * is intended to implement backup and restore functionality, while + * maintaining files in their encrypted state. + * + * @param lpFileName + * The name of the file to be opened. The string must consist of + * characters from the Windows character set. + * @param ulFlags + * The operation to be performed. + * @param pvContext + * The address of a context block that must be presented in subsequent + * calls to ReadEncryptedFileRaw, WriteEncryptedFileRaw, or + * CloseEncryptedFileRaw. Do not modify it. + * @return If the function succeeds, it returns ERROR_SUCCESS. If the function + * fails, it returns a nonzero error code defined in WinError.h. You can use + * FormatMessage with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic + * text description of the error. + */ + int OpenEncryptedFileRaw(String lpFileName, ULONG ulFlags, PointerByReference pvContext); + + /** + * Backs up (export) encrypted files. This is one of a group of Encrypted File + * System (EFS) functions that is intended to implement backup and restore + * functionality, while maintaining files in their encrypted state. + * + * @param pfExportCallback + * A pointer to the export callback function. The system calls the + * callback function multiple times, each time passing a block of the + * file's data to the callback function until the entire file has been + * read. For more information, see ExportCallback. + * @param pvCallbackContext + * A pointer to an application-defined and allocated context block. + * The system passes this pointer to the callback function as a + * parameter so that the callback function can have access to + * application-specific data. This can be a structure and can contain + * any data the application needs, such as the handle to the file that + * will contain the backup copy of the encrypted file. + * @param pvContext + * A pointer to a system-defined context block. The context block is + * returned by the OpenEncryptedFileRaw function. Do not modify it. + * @return If the function succeeds, the return value is ERROR_SUCCESS. If the + * function fails, it returns a nonzero error code defined in WinError.h. You + * can use FormatMessage with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a + * generic text description of the error. + */ + int ReadEncryptedFileRaw(FE_EXPORT_FUNC pfExportCallback, + Pointer pvCallbackContext, Pointer pvContext); + + /** + * Restores (import) encrypted files. This is one of a group of Encrypted File + * System (EFS) functions that is intended to implement backup and restore + * functionality, while maintaining files in. + * + * @param pfImportCallback + * A pointer to the import callback function. The system calls the + * callback function multiple times, each time passing a buffer that + * will be filled by the callback function with a portion of backed-up + * file's data. When the callback function signals that the entire + * file has been processed, it tells the system that the restore + * operation is finished. For more information, see ImportCallback. + * @param pvCallbackContext + * A pointer to an application-defined and allocated context block. + * The system passes this pointer to the callback function as a + * parameter so that the callback function can have access to + * application-specific data. This can be a structure and can contain + * any data the application needs, such as the handle to the file that + * will contain the backup copy of the encrypted file. + * @param pvContext + * A pointer to a system-defined context block. The context block is + * returned by the OpenEncryptedFileRaw function. Do not modify it. + * @return If the function succeeds, the return value is ERROR_SUCCESS. If the + * function fails, it returns a nonzero error code defined in WinError.h. You + * can use FormatMessage with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a + * generic text description of the error. + */ + int WriteEncryptedFileRaw(FE_IMPORT_FUNC pfImportCallback, + Pointer pvCallbackContext, Pointer pvContext); + + /** + * Closes an encrypted file after a backup or restore operation, and frees + * associated system resources. This is one of a group of Encrypted File + * System (EFS) functions that is intended to implement backup and restore + * functionality, while maintaining files in their encrypted state. + * + * @param pvContext + * A pointer to a system-defined context block. The + * OpenEncryptedFileRaw function returns the context block. + */ + void CloseEncryptedFileRaw(Pointer pvContext); + + /** + * + BOOL WINAPI CreateProcessWithLogonW( + _In_ LPCWSTR lpUsername, + _In_opt_ LPCWSTR lpDomain, + _In_ LPCWSTR lpPassword, + _In_ DWORD dwLogonFlags, + _In_opt_ LPCWSTR lpApplicationName, + _Inout_opt_ LPWSTR lpCommandLine, + _In_ DWORD dwCreationFlags, + _In_opt_ LPVOID lpEnvironment, + _In_opt_ LPCWSTR lpCurrentDirectory, + _In_ LPSTARTUPINFOW lpStartupInfo, + _Out_ LPPROCESS_INFORMATION lpProcessInfo + ); + * + * + * @param lpUsername + * [in]
    + * The name of the user. This is the name of the user account to + * log on to.
    + * If you use the UPN format, user@DNS_domain_name, the lpDomain + * parameter must be NULL.
    + * The user account must have the Log On Locally permission on + * the local computer.
    + * This permission is granted to all users on workstations and + * servers, but only to administrators on domain controllers. + * @param lpDomain + * [in, optional]
    + * The name of the domain or server whose account database + * contains the lpUsername account.
    + * If this parameter is NULL, the user name must be specified in + * UPN format. + * @param lpPassword + * [in]
    + * The clear-text password for the lpUsername account. + * @param dwLogonFlags + * [in]
    + * The logon option. This parameter can be 0 (zero) or one of the + * following values.
    + * LOGON_WITH_PROFILE: 0x00000001
    + * Log on, then load the user profile in the HKEY_USERS registry + * key.
    + * The function returns after the profile is loaded.
    + * Loading the profile can be time-consuming, so it is best to + * use this value only if you must access the information in the + * HKEY_CURRENT_USER registry key.
    + * Windows Server 2003: The profile is unloaded after the new + * process is terminated, whether or not it has created child + * processes.
    + * Windows XP: The profile is unloaded after the new process and + * all child processes it has created are terminated.
    + *
    + * LOGON_NETCREDENTIALS_ONLY: 0x00000002
    + * Log on, but use the specified credentials on the network only. + *
    + * The new process uses the same token as the caller, but the + * system creates a new logon session within LSA, and the process + * uses the specified credentials as the default credentials. + *
    + * This value can be used to create a process that uses a + * different set of credentials locally than it does remotely. + *
    + * This is useful in inter-domain scenarios where there is no + * trust relationship.
    + * The system does not validate the specified credentials.
    + * Therefore, the process can start, but it may not have access + * to network resources. + * @param lpApplicationName + * [in, optional]
    + * The name of the module to be executed. This module can be a + * Windows-based application.
    + * It can be some other type of module (for example, MS-DOS or + * OS/2) if the appropriate subsystem is available on the local + * computer. The string can specify the full path and file name + * of the module to execute or it can specify a partial name. + *
    + * If it is a partial name, the function uses the current drive + * and current directory to complete the specification.
    + * The function does not use the search path. This parameter must + * include the file name extension; no default extension is + * assumed. The lpApplicationName parameter can be NULL, and the + * module name must be the first white space-delimited token in + * the lpCommandLine string.
    + * If you are using a long file name that contains a space, use + * quoted strings to indicate where the file name ends and the + * arguments begin; otherwise, the file name is ambiguous. For + * example, the following string can be interpreted in different + * ways:
    + * "c:\program files\sub dir\program name"
    + * The system tries to interpret the possibilities in the + * following order:
    + *
    + * c:\program.exe files\sub dir\program name
    + * c:\program files\sub.exe dir\program name
    + * c:\program files\sub dir\program.exe name
    + * c:\program files\sub dir\program name.exe
    + *
    + * If the executable module is a 16-bit application, + * lpApplicationName should be NULL, and the string pointed to by + * lpCommandLine should specify the executable module and its + * arguments. + * @param lpCommandLine + * [in, out, optional]
    + * The command line to be executed. The maximum length of this + * string is 1024 characters.
    + * If lpApplicationName is NULL, the module name portion of + * lpCommandLine is limited to MAX_PATH characters.
    + * The function can modify the contents of this string.
    + * Therefore, this parameter cannot be a pointer to read-only + * memory (such as a const variable or a literal string).
    + * If this parameter is a constant string, the function may cause + * an access violation.
    + * The lpCommandLine parameter can be NULL, and the function uses + * the string pointed to by lpApplicationNameas the command line. + *
    + *
    + * If both lpApplicationName and lpCommandLine are non-NULL, + * *lpApplicationName specifies the module to execute, and + * *lpCommandLine specifies the command line.
    + * The new process can use GetCommandLine to retrieve the entire + * command line.
    + * Console processes written in C can use the argc and argv + * arguments to parse the command line.
    + * Because argv[0] is the module name, C programmers typically + * repeat the module name as the first token in the command line. + *
    + * If lpApplicationName is NULL, the first white space-delimited + * token of the command line specifies the module name.
    + * If you are using a long file name that contains a space, use + * quoted strings to indicate where the file name ends and the + * arguments begin (see the explanation for the lpApplicationName + * parameter). If the file name does not contain an extension, + * .exe is appended. Therefore, if the file name extension is + * .com, this parameter must include the .com extension. If the + * file name ends in a period with no extension, or if the file + * name contains a path, .exe is not appended. If the file name + * does not contain a directory path, the system searches for the + * executable file in the following sequence:
    + *
    + * 1. The directory from which the application loaded.
    + * 2. The current directory for the parent process.
    + * 3. The 32-bit Windows system directory. Use the + * GetSystemDirectory function to get the path of this directory. + *
    + * 4. The 16-bit Windows system directory. There is no function + * that obtains the path of this directory, but it is searched. + *
    + * 5. The Windows directory. Use the GetWindowsDirectory function + * to get the path of this directory.
    + * 6. The directories that are listed in the PATH environment + * variable. Note that this function does not search the + * per-application path specified by the App Paths registry key. + * To include this per-application path in the search sequence, + * use the ShellExecute function.
    + *
    + * The system adds a null character to the command line string to + * separate the file name from the arguments. This divides the + * original string into two strings for internal processing.
    + * @param dwCreationFlags + * The flags that control how the process is created.
    + * The CREATE_DEFAULT_ERROR_MODE, CREATE_NEW_CONSOLE, and + * CREATE_NEW_PROCESS_GROUP flags are enabled by default.
    + * Even if you do not set the flag, the system functions as if it + * were set. You can specify additional flags as noted.
    + *
    + * CREATE_DEFAULT_ERROR_MODE: 0x04000000
    + * The new process does not inherit the error mode of the calling + * process.
    + * Instead, CreateProcessWithLogonW gives the new process the + * current default error mode.
    + * An application sets the current default error mode by calling + * SetErrorMode. This flag is enabled by default.
    + *
    + * CREATE_NEW_CONSOLE: 0x00000010
    + * The new process has a new console, instead of inheriting the + * parent's console. This flag cannot be used with the + * DETACHED_PROCESS flag.
    + * This flag is enabled by default.
    + *
    + * CREATE_NEW_PROCESS_GROUP: 0x00000200
    + * The new process is the root process of a new process group. + *
    + * The process group includes all processes that are descendants + * of this root process.
    + * The process identifier of the new process group is the same as + * the process identifier, which is returned in the lpProcessInfo + * parameter.
    + * Process groups are used by the GenerateConsoleCtrlEvent + * function to enable sending a CTRL+C or CTRL+BREAK signal to a + * group of console processes.
    + * This flag is enabled by default.
    + *
    + * CREATE_SEPARATE_WOW_VDM: 0x00000800
    + * This flag is only valid starting a 16-bit Windows-based + * application.
    + * If set, the new process runs in a private Virtual DOS Machine + * (VDM).
    + * By default, all 16-bit Windows-based applications run in a + * single, shared VDM.
    + * The advantage of running separately is that a crash only + * terminates the single VDM; any other programs running in + * distinct VDMs continue to function normally.
    + * Also, 16-bit Windows-based applications that run in separate + * VDMs have separate input queues, which means that if one + * application stops responding momentarily, applications in + * separate VDMs continue to receive input.
    + * CREATE_SUSPENDED: 0x00000004
    + * The primary thread of the new process is created in a + * suspended state, and does not run until the ResumeThread + * function is called.
    + *
    + * CREATE_UNICODE_ENVIRONMENT: 0x00000400
    + * Indicates the format of the lpEnvironment parameter.
    + * If this flag is set, the environment block pointed to by + * lpEnvironment uses Unicode characters.
    + * Otherwise, the environment block uses ANSI characters.
    + * EXTENDED_STARTUPINFO_PRESENT: 0x00080000
    + * The process is created with extended startup information; the + * lpStartupInfo parameter specifies a STARTUPINFOEX structure. + *
    + * Windows Server 2003 and Windows XP: This value is not + * supported.
    + * @param lpEnvironment + * [in, optional]
    + * A pointer to an environment block for the new process.
    + * If this parameter is NULL, the new process uses an environment + * created from the profile of the user specified by lpUsername. + * An environment block consists of a null-terminated block of + * null-terminated strings.
    + * Each string is in the following form:
    + * name=value
    + * Because the equal sign (=) is used as a separator, it must not + * be used in the name of an environment variable.
    + * An environment block can contain Unicode or ANSI characters. + *
    + * If the environment block pointed to by lpEnvironment contains + * Unicode characters, ensure that dwCreationFlags includes + * CREATE_UNICODE_ENVIRONMENT.
    + * If this parameter is NULL and the environment block of the + * parent process contains Unicode characters, you must also + * ensure that dwCreationFlags includes + * CREATE_UNICODE_ENVIRONMENT.
    + * An ANSI environment block is terminated by two 0 (zero) bytes: + * one for the last string and one more to terminate the block. + *
    + * A Unicode environment block is terminated by four zero bytes: + * two for the last string and two more to terminate the block. + *
    + * To retrieve a copy of the environment block for a specific + * user, use the CreateEnvironmentBlock function.
    + * @param lpCurrentDirectory + * [in, optional]
    + * The full path to the current directory for the process.
    + * The string can also specify a UNC path.
    + * If this parameter is NULL, the new process has the same + * current drive and directory as the calling process.
    + * This feature is provided primarily for shells that need to + * start an application, and specify its initial drive and + * working directory.
    + * @param lpStartupInfo + * [in]
    + * A pointer to a STARTUPINFO or STARTUPINFOEX structure.
    + * The application must add permission for the specified user + * account to the specified window station and desktop, even for + * WinSta0\Default.
    + * If the lpDesktop member is NULL or an empty string, the new + * process inherits the desktop and window station of its parent + * process.
    + * The application must add permission for the specified user + * account to the inherited window station and desktop.
    + * Windows XP: CreateProcessWithLogonW adds permission for the + * specified user account to the inherited window station and + * desktop.
    + * Handles in STARTUPINFO or STARTUPINFOEX must be closed with + * CloseHandle when they are no longer needed.
    + * Important If the dwFlags member of the STARTUPINFO structure + * specifies STARTF_USESTDHANDLES, the standard handle fields are + * copied unchanged to the child process without validation.
    + * The caller is responsible for ensuring that these fields + * contain valid handle values. Incorrect values can cause the + * child process to misbehave or crash.
    + * Use the Application Verifier runtime verification tool to + * detect invalid handles. + * @param lpProcessInfo + * [out]
    + * A pointer to a PROCESS_INFORMATION structure that receives + * identification information for the new process, including a + * handle to the process.
    + * Handles in PROCESS_INFORMATION must be closed with the + * CloseHandle function when they are not needed.
    + * @return If the function succeeds, the return value is nonzero.
    + * If the function fails, the return value is 0 (zero).
    + * To get extended error information, call GetLastError.
    + * Note that the function returns before the process has finished + * initialization.
    + * If a required DLL cannot be located or fails to initialize, the + * process is terminated.
    + * To get the termination status of a process, call + * GetExitCodeProcess. + * @see MSDN + */ + boolean CreateProcessWithLogonW(String lpUsername, String lpDomain, String lpPassword, int dwLogonFlags, + String lpApplicationName, String lpCommandLine, int dwCreationFlags, Pointer lpEnvironment, + String lpCurrentDirectory, STARTUPINFO lpStartupInfo, PROCESS_INFORMATION lpProcessInfo); + } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Advapi32Util.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Advapi32Util.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Advapi32Util.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Advapi32Util.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,18 +1,55 @@ /* Copyright (c) 2010 Daniel Doubrovkine, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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 static com.sun.jna.platform.win32.WinBase.CREATE_FOR_DIR; +import static com.sun.jna.platform.win32.WinBase.CREATE_FOR_IMPORT; +import static com.sun.jna.platform.win32.WinNT.DACL_SECURITY_INFORMATION; +import static com.sun.jna.platform.win32.WinNT.FILE_ALL_ACCESS; +import static com.sun.jna.platform.win32.WinNT.FILE_GENERIC_EXECUTE; +import static com.sun.jna.platform.win32.WinNT.FILE_GENERIC_READ; +import static com.sun.jna.platform.win32.WinNT.FILE_GENERIC_WRITE; +import static com.sun.jna.platform.win32.WinNT.GENERIC_EXECUTE; +import static com.sun.jna.platform.win32.WinNT.GENERIC_READ; +import static com.sun.jna.platform.win32.WinNT.GENERIC_WRITE; +import static com.sun.jna.platform.win32.WinNT.GROUP_SECURITY_INFORMATION; +import static com.sun.jna.platform.win32.WinNT.OWNER_SECURITY_INFORMATION; +import static com.sun.jna.platform.win32.WinNT.PROTECTED_DACL_SECURITY_INFORMATION; +import static com.sun.jna.platform.win32.WinNT.PROTECTED_SACL_SECURITY_INFORMATION; +import static com.sun.jna.platform.win32.WinNT.SACL_SECURITY_INFORMATION; +import static com.sun.jna.platform.win32.WinNT.SE_DACL_PROTECTED; +import static com.sun.jna.platform.win32.WinNT.SE_SACL_PROTECTED; +import static com.sun.jna.platform.win32.WinNT.STANDARD_RIGHTS_READ; +import static com.sun.jna.platform.win32.WinNT.TOKEN_ADJUST_PRIVILEGES; +import static com.sun.jna.platform.win32.WinNT.TOKEN_DUPLICATE; +import static com.sun.jna.platform.win32.WinNT.TOKEN_IMPERSONATE; +import static com.sun.jna.platform.win32.WinNT.TOKEN_QUERY; +import static com.sun.jna.platform.win32.WinNT.UNPROTECTED_DACL_SECURITY_INFORMATION; +import static com.sun.jna.platform.win32.WinNT.UNPROTECTED_SACL_SECURITY_INFORMATION; + import java.io.ByteArrayOutputStream; +import java.io.Closeable; import java.io.File; import java.io.IOException; import java.util.ArrayList; @@ -25,30 +62,35 @@ import com.sun.jna.Memory; import com.sun.jna.Native; import com.sun.jna.Pointer; -import com.sun.jna.WString; +import com.sun.jna.platform.win32.WinBase.FE_EXPORT_FUNC; +import com.sun.jna.platform.win32.WinBase.FE_IMPORT_FUNC; import com.sun.jna.platform.win32.WinBase.FILETIME; +import com.sun.jna.platform.win32.WinDef.BOOLByReference; +import com.sun.jna.platform.win32.WinDef.DWORD; +import com.sun.jna.platform.win32.WinDef.DWORDByReference; +import com.sun.jna.platform.win32.WinDef.ULONG; +import com.sun.jna.platform.win32.WinDef.ULONGByReference; import com.sun.jna.platform.win32.WinNT.ACCESS_ACEStructure; +import com.sun.jna.platform.win32.WinNT.ACCESS_ALLOWED_ACE; import com.sun.jna.platform.win32.WinNT.ACL; import com.sun.jna.platform.win32.WinNT.EVENTLOGRECORD; +import com.sun.jna.platform.win32.WinNT.GENERIC_MAPPING; import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.platform.win32.WinNT.HANDLEByReference; +import com.sun.jna.platform.win32.WinNT.PRIVILEGE_SET; import com.sun.jna.platform.win32.WinNT.PSID; import com.sun.jna.platform.win32.WinNT.PSIDByReference; import com.sun.jna.platform.win32.WinNT.SECURITY_DESCRIPTOR_RELATIVE; +import com.sun.jna.platform.win32.WinNT.SECURITY_IMPERSONATION_LEVEL; import com.sun.jna.platform.win32.WinNT.SID_AND_ATTRIBUTES; import com.sun.jna.platform.win32.WinNT.SID_NAME_USE; +import com.sun.jna.platform.win32.WinNT.TOKEN_TYPE; import com.sun.jna.platform.win32.WinReg.HKEY; import com.sun.jna.platform.win32.WinReg.HKEYByReference; -import com.sun.jna.ptr.ByteByReference; import com.sun.jna.ptr.IntByReference; import com.sun.jna.ptr.LongByReference; import com.sun.jna.ptr.PointerByReference; -import static com.sun.jna.platform.win32.WinDef.BOOLByReference; -import static com.sun.jna.platform.win32.WinDef.DWORD; -import static com.sun.jna.platform.win32.WinDef.DWORDByReference; -import static com.sun.jna.platform.win32.WinNT.*; - /** * Advapi32 utility API. @@ -104,12 +146,12 @@ if (!result) { switch (Kernel32.INSTANCE.GetLastError()) { - case W32Errors.ERROR_INSUFFICIENT_BUFFER: - buffer = new char[len.getValue()]; - break; + case W32Errors.ERROR_INSUFFICIENT_BUFFER: + buffer = new char[len.getValue()]; + break; - default: - throw new Win32Exception(Native.getLastError()); + default: + throw new Win32Exception(Native.getLastError()); } result = Advapi32.INSTANCE.GetUserNameW(buffer, len); @@ -269,9 +311,13 @@ if (!Advapi32.INSTANCE.ConvertSidToStringSid(sid, stringSid)) { throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); } - String result = stringSid.getValue().getWideString(0); - Kernel32.INSTANCE.LocalFree(stringSid.getValue()); - return result; + + Pointer ptr = stringSid.getValue(); + try { + return ptr.getWideString(0); + } finally { + Kernel32Util.freeLocalMemory(ptr); + } } /** @@ -287,7 +333,13 @@ if (!Advapi32.INSTANCE.ConvertStringSidToSid(sidString, pSID)) { throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); } - return pSID.getValue().getBytes(); + + PSID value = pSID.getValue(); + try { + return value.getBytes(); + } finally { + Kernel32Util.freeLocalMemory(value.getPointer()); + } } /** @@ -305,8 +357,13 @@ if (!Advapi32.INSTANCE.ConvertStringSidToSid(sidString, pSID)) { throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); } - return Advapi32.INSTANCE.IsWellKnownSid(pSID.getValue(), - wellKnownSidType); + + PSID value = pSID.getValue(); + try { + return Advapi32.INSTANCE.IsWellKnownSid(value, wellKnownSidType); + } finally { + Kernel32Util.freeLocalMemory(value.getPointer()); + } } /** @@ -324,7 +381,27 @@ return Advapi32.INSTANCE.IsWellKnownSid(pSID, wellKnownSidType); } + /** + * Align cbAcl on a DWORD + * @param cbAcl size to align + * @return the aligned size + */ + public static int alignOnDWORD(int cbAcl) { + return (cbAcl + (DWORD.SIZE - 1)) & 0xfffffffc; + } + /** + * Helper function to calculate the size of an ACE for a given PSID size + * @param sidLength length of the sid + * @return size of the ACE + */ + public static int getAceSize(int sidLength) { + return Native.getNativeSize(ACCESS_ALLOWED_ACE.class, null) + + sidLength + - DWORD.SIZE; + } + + /** * Get an account name from a string SID on the local machine. * * @param sidString @@ -345,8 +422,7 @@ * @return Account. */ public static Account getAccountBySid(String systemName, String sidString) { - return getAccountBySid(systemName, new PSID( - convertStringSidToSid(sidString))); + return getAccountBySid(systemName, new PSID(convertStringSidToSid(sidString))); } /** @@ -437,28 +513,45 @@ */ public static Account[] getCurrentUserGroups() { HANDLEByReference phToken = new HANDLEByReference(); + Win32Exception err = null; try { // open thread or process token HANDLE threadHandle = Kernel32.INSTANCE.GetCurrentThread(); if (!Advapi32.INSTANCE.OpenThreadToken(threadHandle, TOKEN_DUPLICATE | TOKEN_QUERY, true, phToken)) { - if (W32Errors.ERROR_NO_TOKEN != Kernel32.INSTANCE - .GetLastError()) { - throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + int rc = Kernel32.INSTANCE.GetLastError(); + if (rc != W32Errors.ERROR_NO_TOKEN) { + throw new Win32Exception(rc); } + HANDLE processHandle = Kernel32.INSTANCE.GetCurrentProcess(); if (!Advapi32.INSTANCE.OpenProcessToken(processHandle, TOKEN_DUPLICATE | TOKEN_QUERY, phToken)) { throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); } } + return getTokenGroups(phToken.getValue()); + } catch(Win32Exception e) { + err = e; + throw err; // re-throw in order to invoke finally block } finally { - if (phToken.getValue() != WinBase.INVALID_HANDLE_VALUE) { - if (!Kernel32.INSTANCE.CloseHandle(phToken.getValue())) { - throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + HANDLE hToken = phToken.getValue(); + if (!WinBase.INVALID_HANDLE_VALUE.equals(hToken)) { + try { + Kernel32Util.closeHandle(hToken); + } catch(Win32Exception e) { + if (err == null) { + err = e; + } else { + err.addSuppressed(e); + } } } + + if (err != null) { + throw err; + } } } @@ -595,9 +688,9 @@ && rc != W32Errors.ERROR_INSUFFICIENT_BUFFER) { throw new Win32Exception(rc); } - return Native.toString(data); + return Native.toString(data); } - + /** * Get a registry REG_EXPAND_SZ value. * @@ -658,7 +751,7 @@ } return Native.toString(data); } - + /** * Get a registry REG_MULTI_SZ value. * @@ -731,7 +824,7 @@ } return result.toArray(new String[0]); } - + /** * Get a registry REG_BINARY value. * @@ -792,7 +885,7 @@ } return data; } - + /** * Get a registry DWORD value. * @@ -852,7 +945,7 @@ } return data.getValue(); } - + /** * Get a registry QWORD value. * @@ -880,7 +973,7 @@ } } } - + /** * Get a registry QWORD value. * @@ -948,9 +1041,9 @@ byteData.write(0, lpData, 0, lpcbData.getValue()); if (lpType.getValue() == WinNT.REG_DWORD) { - result = new Integer(byteData.getInt(0)); + result = Integer.valueOf(byteData.getInt(0)); } else if (lpType.getValue() == WinNT.REG_QWORD) { - result = new Long(byteData.getLong(0)); + result = Long.valueOf(byteData.getLong(0)); } else if (lpType.getValue() == WinNT.REG_BINARY) { result = byteData.getByteArray(0, lpcbData.getValue()); } else if ((lpType.getValue() == WinNT.REG_SZ) @@ -1509,7 +1602,7 @@ return phkKey; } - + /** * Close the registry key * @@ -1994,20 +2087,23 @@ // @Override - @todo restore Override annotation after we move to source // level 1.6 - public Iterator iterator() { + @Override + public Iterator iterator() { return this; } // @Override - @todo restore Override annotation after we move to source // level 1.6 - public boolean hasNext() { + @Override + public boolean hasNext() { read(); return !_done; } // @Override - @todo restore Override annotation after we move to source // level 1.6 - public EventLogRecord next() { + @Override + public EventLogRecord next() { read(); EventLogRecord record = new EventLogRecord(_pevlr); _dwRead -= record.getLength(); @@ -2017,7 +2113,8 @@ // @Override - @todo restore Override annotation after we move to source // level 1.6 - public void remove() { + @Override + public void remove() { } } @@ -2032,8 +2129,8 @@ repeat = false; memory = new Memory(nLength); IntByReference lpnSize = new IntByReference(); - boolean succeded = Advapi32.INSTANCE.GetFileSecurity(new WString( - fileName), infoType, memory, nLength, lpnSize); + boolean succeded = Advapi32.INSTANCE.GetFileSecurity( + fileName, infoType, memory, nLength, lpnSize); if (!succeded) { int lastError = Kernel32.INSTANCE.GetLastError(); @@ -2100,7 +2197,7 @@ final IntByReference lpnSize = new IntByReference(); boolean succeeded = Advapi32.INSTANCE.GetFileSecurity( - new WString(absoluteFilePath), + absoluteFilePath, infoType, null, 0, lpnSize); @@ -2114,8 +2211,8 @@ final int nLength = lpnSize.getValue(); final Memory securityDescriptorMemoryPointer = new Memory(nLength); - succeeded = Advapi32.INSTANCE.GetFileSecurity(new WString( - absoluteFilePath), infoType, securityDescriptorMemoryPointer, nLength, lpnSize); + succeeded = Advapi32.INSTANCE.GetFileSecurity( + absoluteFilePath, infoType, securityDescriptorMemoryPointer, nLength, lpnSize); if (!succeeded) { securityDescriptorMemoryPointer.clear(); @@ -2139,13 +2236,13 @@ * @return Memory containing the self relative security descriptor */ public static Memory getSecurityDescriptorForObject(final String absoluteObjectPath, int objectType, boolean getSACL) { - - int infoType = OWNER_SECURITY_INFORMATION + + int infoType = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION - | (getSACL ? SACL_SECURITY_INFORMATION : 0); + | (getSACL ? SACL_SECURITY_INFORMATION : 0); - PointerByReference ppSecurityDescriptor = new PointerByReference(); + PointerByReference ppSecurityDescriptor = new PointerByReference(); int lastError = Advapi32.INSTANCE.GetNamedSecurityInfo( absoluteObjectPath, @@ -2160,14 +2257,19 @@ if (lastError != 0) { throw new Win32Exception(lastError); } - - int nLength = Advapi32.INSTANCE.GetSecurityDescriptorLength(ppSecurityDescriptor.getValue()); - final Memory memory = new Memory(nLength); - memory.write(0, ppSecurityDescriptor.getValue().getByteArray(0, nLength), 0, nLength); - Kernel32.INSTANCE.LocalFree(ppSecurityDescriptor.getValue()); - return memory; + + int nLength = Advapi32.INSTANCE.GetSecurityDescriptorLength(ppSecurityDescriptor.getValue()); + Memory memory = new Memory(nLength); + Pointer secValue = ppSecurityDescriptor.getValue(); + try { + byte[] data = secValue.getByteArray(0, nLength); + memory.write(0, data, 0, nLength); + return memory; + } finally { + Kernel32Util.freeLocalMemory(secValue); + } } - + /** * Set a self relative security descriptor for the given object type. * @@ -2202,53 +2304,53 @@ int objectType, SECURITY_DESCRIPTOR_RELATIVE securityDescriptor, boolean setOwner, - boolean setGroup, + boolean setGroup, boolean setDACL, boolean setSACL, boolean setDACLProtectedStatus, boolean setSACLProtectedStatus) { - + final PSID psidOwner = securityDescriptor.getOwner(); final PSID psidGroup = securityDescriptor.getGroup(); final ACL dacl = securityDescriptor.getDiscretionaryACL(); final ACL sacl = securityDescriptor.getSystemACL(); - int infoType = 0; + int infoType = 0; // Parameter validation and infoType flag setting. if (setOwner) { - if (psidOwner == null) + if (psidOwner == null) throw new IllegalArgumentException("SECURITY_DESCRIPTOR_RELATIVE does not contain owner"); if (!Advapi32.INSTANCE.IsValidSid(psidOwner)) - throw new IllegalArgumentException("Owner PSID is invalid"); + throw new IllegalArgumentException("Owner PSID is invalid"); infoType |= OWNER_SECURITY_INFORMATION; } if (setGroup) { - if (psidGroup == null) + if (psidGroup == null) throw new IllegalArgumentException("SECURITY_DESCRIPTOR_RELATIVE does not contain group"); if (!Advapi32.INSTANCE.IsValidSid(psidGroup)) - throw new IllegalArgumentException("Group PSID is invalid"); + throw new IllegalArgumentException("Group PSID is invalid"); infoType |= GROUP_SECURITY_INFORMATION; } - if (setDACL) { - if (dacl == null) + if (setDACL) { + if (dacl == null) throw new IllegalArgumentException("SECURITY_DESCRIPTOR_RELATIVE does not contain DACL"); if (!Advapi32.INSTANCE.IsValidAcl(dacl.getPointer())) - throw new IllegalArgumentException("DACL is invalid"); + throw new IllegalArgumentException("DACL is invalid"); infoType |= DACL_SECURITY_INFORMATION; } if (setSACL) { - if (sacl == null) + if (sacl == null) throw new IllegalArgumentException("SECURITY_DESCRIPTOR_RELATIVE does not contain SACL"); if (!Advapi32.INSTANCE.IsValidAcl(sacl.getPointer())) - throw new IllegalArgumentException("SACL is invalid"); + throw new IllegalArgumentException("SACL is invalid"); infoType |= SACL_SECURITY_INFORMATION; } - /* - * Control bits SE_DACL_PROTECTED/SE_SACL_PROTECTED indicate the *ACL is protected. The *ACL_SECURITY_INFORMATION flags + /* + * Control bits SE_DACL_PROTECTED/SE_SACL_PROTECTED indicate the *ACL is protected. The *ACL_SECURITY_INFORMATION flags * are meta flags for SetNamedSecurityInfo and are not stored in the SD. If either *ACLProtectedStatus is set, * get the current status from the securityDescriptor and apply as such, otherwise the ACL remains at its default. */ @@ -2291,39 +2393,38 @@ * @return true if has access, otherwise false */ public static boolean accessCheck(File file, AccessCheckPermission permissionToCheck) { - boolean hasAccess = false; - final Memory securityDescriptorMemoryPointer = getSecurityDescriptorForFile(file.getAbsolutePath().replaceAll("/", "\\")); + Memory securityDescriptorMemoryPointer = getSecurityDescriptorForFile(file.getAbsolutePath().replace('/', '\\')); - HANDLEByReference openedAccessToken = null; - final HANDLEByReference duplicatedToken = new HANDLEByReference(); + HANDLEByReference openedAccessToken = new HANDLEByReference(); + HANDLEByReference duplicatedToken = new HANDLEByReference(); + Win32Exception err = null; try{ - openedAccessToken = new HANDLEByReference(); - - final int desireAccess = TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_DUPLICATE | STANDARD_RIGHTS_READ; - if(!Advapi32.INSTANCE.OpenProcessToken(Kernel32.INSTANCE.GetCurrentProcess(), desireAccess, openedAccessToken)) { + int desireAccess = TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_DUPLICATE | STANDARD_RIGHTS_READ; + HANDLE hProcess = Kernel32.INSTANCE.GetCurrentProcess(); + if (!Advapi32.INSTANCE.OpenProcessToken(hProcess, desireAccess, openedAccessToken)) { throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); } - if(!Advapi32.INSTANCE.DuplicateToken(openedAccessToken.getValue(), SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, duplicatedToken)) { + if (!Advapi32.INSTANCE.DuplicateToken(openedAccessToken.getValue(), SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, duplicatedToken)) { throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); } - final GENERIC_MAPPING mapping = new GENERIC_MAPPING(); + GENERIC_MAPPING mapping = new GENERIC_MAPPING(); mapping.genericRead = new DWORD(FILE_GENERIC_READ); mapping.genericWrite = new DWORD(FILE_GENERIC_WRITE); mapping.genericExecute = new DWORD(FILE_GENERIC_EXECUTE); mapping.genericAll = new DWORD(FILE_ALL_ACCESS); - final DWORDByReference rights = new DWORDByReference(new DWORD(permissionToCheck.getCode())); + DWORDByReference rights = new DWORDByReference(new DWORD(permissionToCheck.getCode())); Advapi32.INSTANCE.MapGenericMask(rights, mapping); - final PRIVILEGE_SET privileges = new PRIVILEGE_SET(1); + PRIVILEGE_SET privileges = new PRIVILEGE_SET(1); privileges.PrivilegeCount = new DWORD(0); - final DWORDByReference privilegeLength = new DWORDByReference(new DWORD(privileges.size())); + DWORDByReference privilegeLength = new DWORDByReference(new DWORD(privileges.size())); - final DWORDByReference grantedAccess = new DWORDByReference(); - final BOOLByReference result = new BOOLByReference(); - if(!Advapi32.INSTANCE.AccessCheck(securityDescriptorMemoryPointer, + DWORDByReference grantedAccess = new DWORDByReference(); + BOOLByReference result = new BOOLByReference(); + if (!Advapi32.INSTANCE.AccessCheck(securityDescriptorMemoryPointer, duplicatedToken.getValue(), rights.getValue(), mapping, @@ -2331,28 +2432,33 @@ throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); } - hasAccess = result.getValue().booleanValue(); - + return result.getValue().booleanValue(); + } catch(Win32Exception e) { + err = e; + throw err; // re-throw so finally block executed } finally { - - if(openedAccessToken != null && openedAccessToken.getValue() != null) { - Kernel32.INSTANCE.CloseHandle(openedAccessToken.getValue()); + try { + Kernel32Util.closeHandleRefs(openedAccessToken, duplicatedToken); + } catch(Win32Exception e) { + if (err == null) { + err = e; + } else { + err.addSuppressed(e); + } } - if(duplicatedToken != null && duplicatedToken.getValue() != null) { - Kernel32.INSTANCE.CloseHandle(duplicatedToken.getValue()); + if (securityDescriptorMemoryPointer != null) { + securityDescriptorMemoryPointer.clear(); } - if(securityDescriptorMemoryPointer != null) { - securityDescriptorMemoryPointer.clear(); + if (err != null) { + throw err; } } - - return hasAccess; } - + /** - * Gets a file's Security Descriptor. Convenience wrapper getSecurityDescriptorForObject. + * Gets a file's Security Descriptor. Convenience wrapper getSecurityDescriptorForObject. * * @param file * File object containing a path to a file system object. @@ -2367,9 +2473,9 @@ sdr = new SECURITY_DESCRIPTOR_RELATIVE(securityDesc); return sdr; } - + /** - * Sets a file's Security Descriptor. Convenience wrapper setSecurityDescriptorForObject. + * Sets a file's Security Descriptor. Convenience wrapper setSecurityDescriptorForObject. * @param file * File object containing a path to a file system object. * @param securityDescriptor @@ -2377,7 +2483,7 @@ * @param setOwner * Set the owner. See {@link Advapi32#SetNamedSecurityInfo} for process privilege requirements in setting the owner. * @param setGroup - * Set the group. + * Set the group. * @param setDACL * Set the DACL. * @param setSACL @@ -2385,13 +2491,13 @@ * @param setDACLProtectedStatus * Set DACL protected status as contained within securityDescriptor.control. * @param setSACLProtectedStatus - * Set SACL protected status as contained within securityDescriptor.control. * + * Set SACL protected status as contained within securityDescriptor.control. * */ public static void setFileSecurityDescriptor( File file, SECURITY_DESCRIPTOR_RELATIVE securityDescriptor, boolean setOwner, - boolean setGroup, + boolean setGroup, boolean setDACL, boolean setSACL, boolean setDACLProtectedStatus, @@ -2399,7 +2505,7 @@ { setSecurityDescriptorForObject(file.getAbsolutePath().replaceAll("/", "\\"), AccCtrl.SE_OBJECT_TYPE.SE_FILE_OBJECT, securityDescriptor, setOwner, setGroup, setDACL, setSACL, setDACLProtectedStatus, setSACLProtectedStatus); } - + /** * Encrypts a file or directory. * @@ -2407,7 +2513,7 @@ * The file or directory to encrypt. */ public static void encryptFile(File file) { - WString lpFileName = new WString(file.getAbsolutePath()); + String lpFileName = file.getAbsolutePath(); if (!Advapi32.INSTANCE.EncryptFile(lpFileName)) { throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); } @@ -2420,7 +2526,7 @@ * The file or directory to decrypt. */ public static void decryptFile(File file) { - WString lpFileName = new WString(file.getAbsolutePath()); + String lpFileName = file.getAbsolutePath(); if (!Advapi32.INSTANCE.DecryptFile(lpFileName, new DWORD(0))) { throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); } @@ -2432,10 +2538,10 @@ * @param file * The file to check the status for. * @return The status of the file. - */ + */ public static int fileEncryptionStatus(File file) { DWORDByReference status = new DWORDByReference(); - WString lpFileName = new WString(file.getAbsolutePath()); + String lpFileName = file.getAbsolutePath(); if (!Advapi32.INSTANCE.FileEncryptionStatus(lpFileName, status)) { throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); } @@ -2452,7 +2558,7 @@ * TRUE to disable encryption. FALSE to enable it. */ public static void disableEncryption(File directory, boolean disable) { - WString dirPath = new WString(directory.getAbsolutePath()); + String dirPath = directory.getAbsolutePath(); if (!Advapi32.INSTANCE.EncryptionDisable(dirPath, disable)) { throw new Win32Exception(Native.getLastError()); } @@ -2482,9 +2588,9 @@ if (src.isDirectory()) { writeFlag.setValue(CREATE_FOR_IMPORT | CREATE_FOR_DIR); } - + // open encrypted file for export - WString srcFileName = new WString(src.getAbsolutePath()); + String srcFileName = src.getAbsolutePath(); PointerByReference pvContext = new PointerByReference(); if (Advapi32.INSTANCE.OpenEncryptedFileRaw(srcFileName, readFlag, pvContext) != W32Errors.ERROR_SUCCESS) { @@ -2495,9 +2601,9 @@ final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); FE_EXPORT_FUNC pfExportCallback = new FE_EXPORT_FUNC() { @Override - public DWORD callback(ByteByReference pbData, Pointer pvCallbackContext, + public DWORD callback(Pointer pbData, Pointer pvCallbackContext, ULONG ulLength) { - byte[] arr = pbData.getPointer().getByteArray(0, ulLength.intValue()); + byte[] arr = pbData.getByteArray(0, ulLength.intValue()); try { outputStream.write(arr); } catch (IOException e) { @@ -2507,7 +2613,7 @@ } }; - if (Advapi32.INSTANCE.ReadEncryptedFileRaw(pfExportCallback, null, + if (Advapi32.INSTANCE.ReadEncryptedFileRaw(pfExportCallback, null, pvContext.getValue()) != W32Errors.ERROR_SUCCESS) { throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); } @@ -2521,8 +2627,8 @@ Advapi32.INSTANCE.CloseEncryptedFileRaw(pvContext.getValue()); // open file for import - WString destFileName = new WString(destDir.getAbsolutePath() + File.separator - + src.getName()); + String destFileName = destDir.getAbsolutePath() + File.separator + + src.getName(); pvContext = new PointerByReference(); if (Advapi32.INSTANCE.OpenEncryptedFileRaw(destFileName, writeFlag, pvContext) != W32Errors.ERROR_SUCCESS) { @@ -2533,12 +2639,12 @@ final IntByReference elementsReadWrapper = new IntByReference(0); FE_IMPORT_FUNC pfImportCallback = new FE_IMPORT_FUNC() { @Override - public DWORD callback(ByteByReference pbData, Pointer pvCallbackContext, + public DWORD callback(Pointer pbData, Pointer pvCallbackContext, ULONGByReference ulLength) { int elementsRead = elementsReadWrapper.getValue(); int remainingElements = outputStream.size() - elementsRead; int length = Math.min(remainingElements, ulLength.getValue().intValue()); - pbData.getPointer().write(0, outputStream.toByteArray(), elementsRead, + pbData.write(0, outputStream.toByteArray(), elementsRead, length); elementsReadWrapper.setValue(elementsRead + length); ulLength.setValue(new ULONG(length)); @@ -2546,7 +2652,7 @@ } }; - if (Advapi32.INSTANCE.WriteEncryptedFileRaw(pfImportCallback, null, + if (Advapi32.INSTANCE.WriteEncryptedFileRaw(pfImportCallback, null, pvContext.getValue()) != W32Errors.ERROR_SUCCESS) { throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); } @@ -2554,4 +2660,207 @@ // close Advapi32.INSTANCE.CloseEncryptedFileRaw(pvContext.getValue()); } + + /** + * Convenience class to enable certain Windows process privileges + */ + public static class Privilege implements Closeable { + /** + * If true, the thread is currently impersonating + */ + private boolean currentlyImpersonating = false; + + /** + * If true, the privileges have been enabled + */ + private boolean privilegesEnabled = false; + + /** + * LUID form of the privileges + */ + private final WinNT.LUID[] pLuids; + + /** + * Construct and enable a set of privileges + * @param privileges the names of the privileges in the form of SE_* from Advapi32.java + * @throws IllegalArgumentException + */ + public Privilege(String... privileges) throws IllegalArgumentException, Win32Exception { + pLuids = new WinNT.LUID[privileges.length]; + int i = 0; + for (String p : privileges) { + pLuids[i] = new WinNT.LUID(); + if (!Advapi32.INSTANCE.LookupPrivilegeValue(null, p, pLuids[i])) { + throw new IllegalArgumentException("Failed to find privilege \"" + privileges[i] + "\" - " + Kernel32.INSTANCE.GetLastError()); + } + i++; + } + } + + /** + * Calls disable() to remove the privileges + * @see java.io.Closeable#close() + */ + @Override + public void close() { + this.disable(); + } + + /** + * Enables the given privileges. If required, it will duplicate the process token. No resources are left open when this completes. That is, it is + * NOT required to drop the privileges, although it is considered a best practice if you do not need it. This class is state full. It keeps track + * of whether it has enabled the privileges. Multiple calls to enable() without a drop() in between have no affect. + * @return pointer to self (Privilege) as a convenience for try with resources statements + * @throws Win32Exception + */ + public Privilege enable() throws Win32Exception { + // Ignore if already enabled. + if (privilegesEnabled) + return this; + + // Get thread token + final HANDLEByReference phThreadToken = new HANDLEByReference(); + + try { + phThreadToken.setValue(getThreadToken()); + WinNT.TOKEN_PRIVILEGES tp = new WinNT.TOKEN_PRIVILEGES(pLuids.length); + for (int i = 0; i < pLuids.length; i++) { + tp.Privileges[i] = new WinNT.LUID_AND_ATTRIBUTES(pLuids[i], new DWORD(WinNT.SE_PRIVILEGE_ENABLED)); + } + if (!Advapi32.INSTANCE.AdjustTokenPrivileges(phThreadToken.getValue(), false, tp, 0, null, null)) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + privilegesEnabled = true; + } + catch (Win32Exception ex) { + // If fails, clean up + if (currentlyImpersonating) { + Advapi32.INSTANCE.SetThreadToken(null, null); + currentlyImpersonating = false; + } + else { + if (privilegesEnabled) { + WinNT.TOKEN_PRIVILEGES tp = new WinNT.TOKEN_PRIVILEGES(pLuids.length); + for (int i = 0; i < pLuids.length; i++) { + tp.Privileges[i] = new WinNT.LUID_AND_ATTRIBUTES(pLuids[i], new DWORD(0)); + } + Advapi32.INSTANCE.AdjustTokenPrivileges(phThreadToken.getValue(), false, tp, 0, null, null); + privilegesEnabled = false; + } + } + throw ex; + } + finally { + // Always close the thread token + if ((phThreadToken.getValue() != WinBase.INVALID_HANDLE_VALUE) + && (phThreadToken.getValue() != null)) { + Kernel32.INSTANCE.CloseHandle(phThreadToken.getValue()); + phThreadToken.setValue(null); + } + } + return this; + } + + /** + * Disabled the prior enabled privilege + * @throws Win32Exception + */ + public void disable() throws Win32Exception { + // Get thread token + final HANDLEByReference phThreadToken = new HANDLEByReference(); + + try { + phThreadToken.setValue(getThreadToken()); + if (currentlyImpersonating) { + Advapi32.INSTANCE.SetThreadToken(null, null); + } + else + { + if (privilegesEnabled) { + WinNT.TOKEN_PRIVILEGES tp = new WinNT.TOKEN_PRIVILEGES(pLuids.length); + for (int i = 0; i < pLuids.length; i++) { + tp.Privileges[i] = new WinNT.LUID_AND_ATTRIBUTES(pLuids[i], new DWORD(0)); + } + Advapi32.INSTANCE.AdjustTokenPrivileges(phThreadToken.getValue(), false, tp, 0, null, null); + privilegesEnabled = false; + } + } + } + finally { + // Close the thread token + if ((phThreadToken.getValue() != WinBase.INVALID_HANDLE_VALUE) + && (phThreadToken.getValue() != null)) { + Kernel32.INSTANCE.CloseHandle(phThreadToken.getValue()); + phThreadToken.setValue(null); + } + } + } + + /** + * Get a handle to the thread token. May duplicate the process token + * and set as the thread token if ther thread has no token. + * @return HANDLE to the thread token + * @throws Win32Exception + */ + private HANDLE getThreadToken() throws Win32Exception { + // we need to create a new token here for the duplicate + final HANDLEByReference phThreadToken = new HANDLEByReference(); + final HANDLEByReference phProcessToken = new HANDLEByReference(); + + try { + // open thread token + if (!Advapi32.INSTANCE.OpenThreadToken(Kernel32.INSTANCE.GetCurrentThread(), + TOKEN_ADJUST_PRIVILEGES, + false, + phThreadToken)) { + // OpenThreadToken may fail with W32Errors.ERROR_NO_TOKEN if current thread is anonymous. Check for that condition here. If not, throw an error. + int lastError = Kernel32.INSTANCE.GetLastError(); + if (W32Errors.ERROR_NO_TOKEN != lastError) { + throw new Win32Exception(lastError); + } + + // Due to ERROR_NO_TOKEN, we need to open the process token to duplicate it, then set our thread token. + if (!Advapi32.INSTANCE.OpenProcessToken(Kernel32.INSTANCE.GetCurrentProcess(), TOKEN_DUPLICATE, phProcessToken)) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + // Process token opened, now duplicate + if (!Advapi32.INSTANCE.DuplicateTokenEx(phProcessToken.getValue(), + TOKEN_ADJUST_PRIVILEGES | TOKEN_IMPERSONATE, + null, + SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, + TOKEN_TYPE.TokenImpersonation, + phThreadToken)) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + // And set thread token. + if (!Advapi32.INSTANCE.SetThreadToken(null, phThreadToken.getValue())) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + currentlyImpersonating = true; + } + } + catch (Win32Exception ex) { + // Close the thread token + if ((phThreadToken.getValue() != WinBase.INVALID_HANDLE_VALUE) + && (phThreadToken.getValue() != null)) { + Kernel32.INSTANCE.CloseHandle(phThreadToken.getValue()); + phThreadToken.setValue(null); + } + throw ex; + } + finally + { + // Always close the process token + if ((phProcessToken.getValue() != WinBase.INVALID_HANDLE_VALUE) + && (phProcessToken.getValue() != null)) { + Kernel32.INSTANCE.CloseHandle(phProcessToken.getValue()); + phProcessToken.setValue(null); + } + } + + return phThreadToken.getValue(); + } + } } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/BaseTSD.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/BaseTSD.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/BaseTSD.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/BaseTSD.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,32 +1,43 @@ /* Copyright (c) 2010 Daniel Doubrovkine, All Rights Reserved -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation; either -* version 2.1 of the License, or (at your option) any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -* Lesser General Public License for more details. -*/ + * + * 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.IntegerType; import com.sun.jna.Pointer; import com.sun.jna.ptr.ByReference; -import com.sun.jna.win32.StdCallLibrary; /** * Based on basetsd.h (various types) * @author dblock[at]dblock[dot]org */ @SuppressWarnings("serial") -public interface BaseTSD extends StdCallLibrary { +public interface BaseTSD { + /** -* Signed long type for pointer precision. -* Use when casting a pointer to a long to perform pointer arithmetic. -*/ + * Signed long type for pointer precision. + * Use when casting a pointer to a long to perform pointer arithmetic. + */ public static class LONG_PTR extends IntegerType { public LONG_PTR() { this(0); @@ -124,4 +135,4 @@ super(value); } } -} \ No newline at end of file +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/COMBindingBaseObject.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/COMBindingBaseObject.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/COMBindingBaseObject.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/COMBindingBaseObject.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,20 +1,32 @@ /* Copyright (c) 2012 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM; import com.sun.jna.WString; import com.sun.jna.platform.win32.Guid; import com.sun.jna.platform.win32.Guid.CLSID; +import com.sun.jna.platform.win32.Guid.GUID; import com.sun.jna.platform.win32.Guid.REFIID; import com.sun.jna.platform.win32.Kernel32; import com.sun.jna.platform.win32.OaIdl; @@ -34,7 +46,6 @@ import com.sun.jna.ptr.IntByReference; import com.sun.jna.ptr.PointerByReference; -// TODO: Auto-generated Javadoc /** * Helper class to provide basic COM support. * @@ -73,63 +84,36 @@ public COMBindingBaseObject(CLSID clsid, boolean useActiveInstance, int dwClsContext) { - // Initialize COM for this thread... - HRESULT hr = Ole32.INSTANCE.CoInitializeEx(null, Ole32.COINIT_APARTMENTTHREADED); - - if (COMUtils.FAILED(hr)) { - Ole32.INSTANCE.CoUninitialize(); - throw new COMException("CoInitialize() failed!"); - } - - if (useActiveInstance) { - hr = OleAuto.INSTANCE.GetActiveObject(clsid, null, this.pUnknown); - - if (COMUtils.SUCCEEDED(hr)) { - this.iUnknown = new Unknown(this.pUnknown.getValue()); - hr = iUnknown.QueryInterface(new REFIID.ByValue( IDispatch.IID_IDISPATCH), - this.pDispatch); - } else { - hr = Ole32.INSTANCE.CoCreateInstance(clsid, null, dwClsContext, - IDispatch.IID_IDISPATCH, this.pDispatch); - } - } else { - hr = Ole32.INSTANCE.CoCreateInstance(clsid, null, dwClsContext, - IDispatch.IID_IDISPATCH, this.pDispatch); - } - - if (COMUtils.FAILED(hr)) { - throw new COMException("COM object with CLSID " - + clsid.toGuidString() + " not registered properly!"); - } - - this.iDispatch = new Dispatch(this.pDispatch.getValue()); + assert COMUtils.comIsInitialized() : "COM not initialized"; + + init(useActiveInstance, clsid, dwClsContext); } public COMBindingBaseObject(String progId, boolean useActiveInstance, int dwClsContext) throws COMException { - // Initialize COM for this thread... - HRESULT hr = Ole32.INSTANCE.CoInitializeEx(null, Ole32.COINIT_APARTMENTTHREADED); - - if (COMUtils.FAILED(hr)) { - this.release(); - throw new COMException("CoInitialize() failed!"); - } + assert COMUtils.comIsInitialized() : "COM not initialized"; - // Get CLSID for Word.Application... CLSID.ByReference clsid = new CLSID.ByReference(); - hr = Ole32.INSTANCE.CLSIDFromProgID(progId, clsid); + HRESULT hr = Ole32.INSTANCE.CLSIDFromProgID(progId, clsid); - if (COMUtils.FAILED(hr)) { - Ole32.INSTANCE.CoUninitialize(); - throw new COMException("CLSIDFromProgID() failed!"); - } + COMUtils.checkRC(hr); + + init(useActiveInstance, clsid, dwClsContext); + } + + public COMBindingBaseObject(String progId, boolean useActiveInstance) + throws COMException { + this(progId, useActiveInstance, WTypes.CLSCTX_SERVER); + } + private void init(boolean useActiveInstance, GUID clsid, int dwClsContext) throws COMException { + HRESULT hr; if (useActiveInstance) { hr = OleAuto.INSTANCE.GetActiveObject(clsid, null, this.pUnknown); if (COMUtils.SUCCEEDED(hr)) { this.iUnknown = new Unknown(this.pUnknown.getValue()); - hr = iUnknown.QueryInterface(new REFIID.ByValue(IDispatch.IID_IDISPATCH), + hr = iUnknown.QueryInterface(new REFIID( IDispatch.IID_IDISPATCH), this.pDispatch); } else { hr = Ole32.INSTANCE.CoCreateInstance(clsid, null, dwClsContext, @@ -139,21 +123,12 @@ hr = Ole32.INSTANCE.CoCreateInstance(clsid, null, dwClsContext, IDispatch.IID_IDISPATCH, this.pDispatch); } - - if (COMUtils.FAILED(hr)) { - throw new COMException("COM object with ProgID '" + progId - + "' and CLSID " + clsid.toGuidString() - + " not registered properly!"); - } - + + COMUtils.checkRC(hr); + this.iDispatch = new Dispatch(this.pDispatch.getValue()); } - - public COMBindingBaseObject(String progId, boolean useActiveInstance) - throws COMException { - this(progId, useActiveInstance, WTypes.CLSCTX_SERVER); - } - + /** * Gets the i dispatch. * @@ -194,10 +169,9 @@ * Release. */ public void release() { - if (this.iDispatch != null) + if (this.iDispatch != null) { this.iDispatch.Release(); - - Ole32.INSTANCE.CoUninitialize(); + } } protected HRESULT oleMethod(int nType, VARIANT.ByReference pvResult, @@ -211,7 +185,7 @@ DISPIDByReference pdispID = new DISPIDByReference(); // Get DISPID for name passed... - HRESULT hr = pDisp.GetIDsOfNames(new REFIID.ByValue(Guid.IID_NULL), ptName, 1, + HRESULT hr = pDisp.GetIDsOfNames(new REFIID(Guid.IID_NULL), ptName, 1, LOCALE_USER_DEFAULT, pdispID); COMUtils.checkRC(hr); @@ -247,24 +221,51 @@ // Handle special-case for property-puts! if (nType == OleAuto.DISPATCH_PROPERTYPUT) { - dp.cNamedArgs = new UINT(_argsLen); - dp.rgdispidNamedArgs = new DISPIDByReference( - OaIdl.DISPID_PROPERTYPUT); + dp.setRgdispidNamedArgs(new DISPID[] {OaIdl.DISPID_PROPERTYPUT}); } // Build DISPPARAMS if (_argsLen > 0) { - dp.cArgs = new UINT(_args.length); - // make pointer of variant array - dp.rgvarg = new VariantArg.ByReference(_args); + dp.setArgs(_args); // write 'DISPPARAMS' structure to memory dp.write(); } + // Apply "fix" according to + // https://www.delphitools.info/2013/04/30/gaining-visual-basic-ole-super-powers/ + // https://msdn.microsoft.com/en-us/library/windows/desktop/ms221486(v=vs.85).aspx + // + // Summary: there are methods in the word typelibrary that require both + // PROPERTYGET _and_ METHOD to be set. With only one of these set the call + // fails. + // + // The article from delphitools argues, that automation compatible libraries + // need to be compatible with VisualBasic which does not distingish methods + // and property getters and will set both flags always. + // + // The MSDN article advises this behaviour: "[...] Some languages cannot + // distinguish between retrieving a property and calling a method. In this + //case, you should set the flags DISPATCH_PROPERTYGET and DISPATCH_METHOD. + // [...]")) + // + // This was found when trying to bind InchesToPoints from the _Application + // dispatch interface of the MS Word 15 type library + // + // The signature according the ITypeLib Viewer (OLE/COM Object Viewer): + // [id(0x00000172), helpcontext(0x09700172)] + // single InchesToPoints([in] single Inches); + + final int finalNType; + if (nType == OleAuto.DISPATCH_METHOD || nType == OleAuto.DISPATCH_PROPERTYGET) { + finalNType = OleAuto.DISPATCH_METHOD | OleAuto.DISPATCH_PROPERTYGET; + } else { + finalNType = nType; + } + // Make the call! - HRESULT hr = pDisp.Invoke(dispId, new REFIID.ByValue(Guid.IID_NULL), LOCALE_SYSTEM_DEFAULT, - new WinDef.WORD(nType), dp, pvResult, pExcepInfo, puArgErr); + HRESULT hr = pDisp.Invoke(dispId, new REFIID(Guid.IID_NULL), LOCALE_SYSTEM_DEFAULT, + new WinDef.WORD(finalNType), dp, pvResult, pExcepInfo, puArgErr); COMUtils.checkRC(hr, pExcepInfo, puArgErr); return hr; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/COMEarlyBindingObject.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/COMEarlyBindingObject.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/COMEarlyBindingObject.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/COMEarlyBindingObject.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,20 +1,30 @@ /* Copyright (c) 2012 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM; import com.sun.jna.WString; import com.sun.jna.platform.win32.Guid.CLSID; -import com.sun.jna.platform.win32.Guid.IID; import com.sun.jna.platform.win32.Guid.REFIID; import com.sun.jna.platform.win32.OaIdl.DISPID; import com.sun.jna.platform.win32.OaIdl.DISPIDByReference; @@ -22,7 +32,6 @@ import com.sun.jna.platform.win32.OleAuto; import com.sun.jna.platform.win32.OleAuto.DISPPARAMS; import com.sun.jna.platform.win32.Variant.VARIANT; -import com.sun.jna.platform.win32.Variant.VARIANT.ByReference; import com.sun.jna.platform.win32.WinDef.LCID; import com.sun.jna.platform.win32.WinDef.UINT; import com.sun.jna.platform.win32.WinDef.UINTByReference; @@ -59,7 +68,7 @@ } @Override - public HRESULT QueryInterface(REFIID.ByValue riid, PointerByReference ppvObject) { + public HRESULT QueryInterface(REFIID riid, PointerByReference ppvObject) { return this.getIDispatch().QueryInterface(riid, ppvObject); } @@ -85,14 +94,14 @@ } @Override - public HRESULT GetIDsOfNames(REFIID.ByValue riid, WString[] rgszNames, int cNames, + public HRESULT GetIDsOfNames(REFIID riid, WString[] rgszNames, int cNames, LCID lcid, DISPIDByReference rgDispId) { return this.getIDispatch().GetIDsOfNames(riid, rgszNames, cNames, lcid, rgDispId); } @Override - public HRESULT Invoke(DISPID dispIdMember, REFIID.ByValue riid, LCID lcid, + public HRESULT Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS.ByReference pDispParams, VARIANT.ByReference pVarResult, EXCEPINFO.ByReference pExcepInfo, IntByReference puArgErr) { diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/COMException.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/COMException.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/COMException.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/COMException.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2012 Tobias Wolf, 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM; @@ -18,19 +29,20 @@ // TODO: Auto-generated Javadoc /** * Exception class for all COM related classes. - * + * * @author Tobias Wolf, wolf.tobias@gmx.net */ public class COMException extends RuntimeException { + private static final long serialVersionUID = 1L; /** The p excep info. */ private EXCEPINFO pExcepInfo; /** The pu arg err. */ private IntByReference puArgErr; - + private int uArgErr; - + /** * Instantiates a new automation exception. */ @@ -40,7 +52,7 @@ /** * Instantiates a new automation exception. - * + * * @param message * the message * @param cause @@ -52,7 +64,7 @@ /** * Instantiates a new automation exception. - * + * * @param message * the message */ @@ -62,7 +74,7 @@ /** * Instantiates a new automation exception. - * + * * @param message * the message * @param pExcepInfo @@ -79,7 +91,7 @@ /** * Instantiates a new automation exception. - * + * * @param cause * the cause */ @@ -89,7 +101,7 @@ /** * Gets the excep info. - * + * * @return the excep info */ public EXCEPINFO getExcepInfo() { @@ -98,7 +110,7 @@ /** * Gets the arg err. - * + * * @return the arg err */ public IntByReference getArgErr() { diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/COMInvoker.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/COMInvoker.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/COMInvoker.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/COMInvoker.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2013 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM; @@ -27,8 +38,7 @@ return func.invokeInt(args); } - protected Object _invokeNativeObject(int vtableId, Object[] args, - Class returnType) { + protected Object _invokeNativeObject(int vtableId, Object[] args, Class returnType) { Pointer vptr = this.getPointer().getPointer(0); // we take the vtable id and multiply with the pointer size (4 bytes on // 32bit OS) @@ -36,7 +46,7 @@ * Pointer.SIZE)); return func.invoke(returnType, args); } - + protected void _invokeNativeVoid(int vtableId, Object[] args) { Pointer vptr = this.getPointer().getPointer(0); // we take the vtable id and multiply with the pointer size (4 bytes on @@ -45,5 +55,5 @@ * Pointer.SIZE)); func.invokeVoid(args); } - + } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/COMLateBindingObject.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/COMLateBindingObject.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/COMLateBindingObject.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/COMLateBindingObject.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,25 +1,33 @@ /* Copyright (c) 2012 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM; import java.util.Date; import com.sun.jna.platform.win32.Guid.CLSID; -import com.sun.jna.platform.win32.OaIdl.VARIANT_BOOL; import com.sun.jna.platform.win32.OleAuto; import com.sun.jna.platform.win32.Variant.VARIANT; -import com.sun.jna.platform.win32.WinDef.LONG; -import com.sun.jna.platform.win32.WinDef.SHORT; // TODO: Auto-generated Javadoc /** @@ -132,7 +140,7 @@ IDispatch iDispatch) { VARIANT.ByReference result = new VARIANT.ByReference(); this.oleMethod(OleAuto.DISPATCH_PROPERTYGET, result, - this.getIDispatch(), propertyName); + iDispatch, propertyName); return ((IDispatch) result.getValue()); } @@ -149,7 +157,7 @@ this.oleMethod(OleAuto.DISPATCH_PROPERTYGET, result, this.getIDispatch(), propertyName); - return (((VARIANT_BOOL) result.getValue()).intValue() != 0); + return result.booleanValue(); } /** @@ -179,7 +187,7 @@ this.oleMethod(OleAuto.DISPATCH_PROPERTYGET, result, this.getIDispatch(), propertyName); - return ((LONG) result.getValue()).intValue(); + return result.intValue(); } /** @@ -194,7 +202,7 @@ this.oleMethod(OleAuto.DISPATCH_PROPERTYGET, result, this.getIDispatch(), propertyName); - return ((SHORT) result.getValue()).shortValue(); + return result.shortValue(); } /** @@ -209,7 +217,7 @@ this.oleMethod(OleAuto.DISPATCH_PROPERTYGET, result, this.getIDispatch(), propertyName); - return result.getValue().toString(); + return result.stringValue(); } /** diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/COMUtils.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/COMUtils.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/COMUtils.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/COMUtils.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,34 +1,47 @@ /* Copyright (c) 2013 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM; +import com.sun.jna.LastErrorException; import java.util.ArrayList; import com.sun.jna.Native; +import com.sun.jna.Pointer; import com.sun.jna.platform.win32.Advapi32; import com.sun.jna.platform.win32.Advapi32Util; import com.sun.jna.platform.win32.Advapi32Util.EnumKey; import com.sun.jna.platform.win32.Advapi32Util.InfoKey; import com.sun.jna.platform.win32.Kernel32Util; import com.sun.jna.platform.win32.OaIdl.EXCEPINFO; -import com.sun.jna.platform.win32.WTypes.BSTR; +import com.sun.jna.platform.win32.Ole32; +import com.sun.jna.platform.win32.W32Errors; import com.sun.jna.platform.win32.WinNT; import com.sun.jna.platform.win32.WinNT.HRESULT; import com.sun.jna.platform.win32.WinReg; import com.sun.jna.platform.win32.WinReg.HKEYByReference; import com.sun.jna.ptr.IntByReference; -// TODO: Auto-generated Javadoc /** * The Class COMUtils. * @@ -108,8 +121,14 @@ public static void checkRC(HRESULT hr, EXCEPINFO pExcepInfo, IntByReference puArgErr) { if (FAILED(hr)) { - String formatMessageFromHR = Kernel32Util.formatMessage(hr); - throw new COMException(formatMessageFromHR, pExcepInfo, puArgErr); + String formatMessage; + try { + formatMessage = Kernel32Util.formatMessage(hr) + "(HRESULT: " + Integer.toHexString(hr.intValue()) + ")"; + } catch (LastErrorException ex) { + // throws if HRESULT can't be resolved + formatMessage = "(HRESULT: " + Integer.toHexString(hr.intValue()) + ")"; + } + throw new COMException(formatMessage, pExcepInfo, puArgErr); } } @@ -184,6 +203,36 @@ } /** + * Check if COM was initialized correctly. The initialization status is not changed! + * + *

    This is a debug function, not for normal usage!

    + * + * @return whether COM has been initialized + */ + public static boolean comIsInitialized() { + WinNT.HRESULT hr = Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED); + if (hr.equals(W32Errors.S_OK)) { + // User failed - uninitialize again and return false + Ole32.INSTANCE.CoUninitialize(); + return false; + } else if (hr.equals(W32Errors.S_FALSE)) { + // OK Variant 1 - User initialized COM with same threading module as + // in this check. According to MSDN CoUninitialize needs to be called + // in this case. + Ole32.INSTANCE.CoUninitialize(); + return true; + } else if (hr.intValue() == W32Errors.RPC_E_CHANGED_MODE) { + return true; + } + // If another result than the checked ones above happens handling is + // delegated to the "normal" COM exception handling and a COMException + // will be raised. + COMUtils.checkRC(hr); + // The return will not be met, as COMUtils#checkRC will raise an exception + return false; + } + + /** * The Class COMInfo. * * @author wolf.tobias@gmx.net The Class COMInfo. diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/ConnectionPointContainer.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/ConnectionPointContainer.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/ConnectionPointContainer.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/ConnectionPointContainer.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,50 +1,61 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM; - -import com.sun.jna.Pointer; -import com.sun.jna.platform.win32.Guid.REFIID; -import com.sun.jna.platform.win32.WinNT.HRESULT; -import com.sun.jna.ptr.PointerByReference; - -public class ConnectionPointContainer extends Unknown implements - IConnectionPointContainer { - - public ConnectionPointContainer(Pointer pointer) { - super(pointer); - } - - public HRESULT EnumConnectionPoints() { - // I think the magic number here is worked out by counting the number of - // methods in the full interface, as this inherits IUnknown, which - // has 3 methods, we start here at 3 (0 indexed). - final int vTableId = 3; - - -// return (HRESULT) this._invokeNativeObject(3, -// new Object[] { this.getPointer(), riid, ppCP }, HRESULT.class); - throw new UnsupportedOperationException(); - } - - @Override - public HRESULT FindConnectionPoint(REFIID riid, PointerByReference ppCP) { - // I think the magic number here is worked out by counting the number of - // methods in the full interface, - // this as this inherits IUnknown, which has 3 methods, we have here 4. - // second in this class - final int vTableId = 4; - return (HRESULT) this._invokeNativeObject(vTableId, - new Object[] { this.getPointer(), riid, ppCP }, HRESULT.class); - } - -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM; + +import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.Guid.REFIID; +import com.sun.jna.platform.win32.WinNT.HRESULT; +import com.sun.jna.ptr.PointerByReference; + +public class ConnectionPointContainer extends Unknown implements + IConnectionPointContainer { + + public ConnectionPointContainer(Pointer pointer) { + super(pointer); + } + + public HRESULT EnumConnectionPoints() { + // I think the magic number here is worked out by counting the number of + // methods in the full interface, as this inherits IUnknown, which + // has 3 methods, we start here at 3 (0 indexed). + final int vTableId = 3; + + +// return (HRESULT) this._invokeNativeObject(3, +// new Object[] { this.getPointer(), riid, ppCP }, HRESULT.class); + throw new UnsupportedOperationException(); + } + + @Override + public HRESULT FindConnectionPoint(REFIID riid, PointerByReference ppCP) { + // I think the magic number here is worked out by counting the number of + // methods in the full interface, + // this as this inherits IUnknown, which has 3 methods, we have here 4. + // second in this class + final int vTableId = 4; + return (HRESULT) this._invokeNativeObject(vTableId, + new Object[] { this.getPointer(), riid, ppCP }, HRESULT.class); + } + +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/ConnectionPoint.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/ConnectionPoint.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/ConnectionPoint.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/ConnectionPoint.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,56 +1,67 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM; - -import com.sun.jna.Pointer; -import com.sun.jna.platform.win32.Guid.IID; -import com.sun.jna.platform.win32.WinDef.DWORD; -import com.sun.jna.platform.win32.WinDef.DWORDByReference; -import com.sun.jna.platform.win32.WinNT.HRESULT; - -public class ConnectionPoint extends Unknown implements IConnectionPoint { - - public ConnectionPoint(Pointer pointer) { - super(pointer); - } - - @Override - public HRESULT GetConnectionInterface(IID iid) { - final int vTableId = 3; - return (HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), iid }, HRESULT.class); - } - - void GetConnectionPointContainer() { - final int vTableId = 4; - - } - - @Override - public HRESULT Advise(IUnknownCallback pUnkSink, DWORDByReference pdwCookie) { - final int vTableId = 5; - - return (HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), pUnkSink.getPointer(), - pdwCookie }, HRESULT.class); - } - - @Override - public HRESULT Unadvise(DWORD dwCookie) { - final int vTableId = 6; - - return (HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), dwCookie }, HRESULT.class); - } - - void EnumConnections() { - final int vTableId = 7; - } -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM; + +import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.Guid.IID; +import com.sun.jna.platform.win32.WinDef.DWORD; +import com.sun.jna.platform.win32.WinDef.DWORDByReference; +import com.sun.jna.platform.win32.WinNT.HRESULT; + +public class ConnectionPoint extends Unknown implements IConnectionPoint { + + public ConnectionPoint(Pointer pointer) { + super(pointer); + } + + @Override + public HRESULT GetConnectionInterface(IID iid) { + final int vTableId = 3; + return (HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), iid }, HRESULT.class); + } + + void GetConnectionPointContainer() { + final int vTableId = 4; + + } + + @Override + public HRESULT Advise(IUnknownCallback pUnkSink, DWORDByReference pdwCookie) { + final int vTableId = 5; + + return (HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), pUnkSink.getPointer(), + pdwCookie }, HRESULT.class); + } + + @Override + public HRESULT Unadvise(DWORD dwCookie) { + final int vTableId = 6; + + return (HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), dwCookie }, HRESULT.class); + } + + void EnumConnections() { + final int vTableId = 7; + } +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/Dispatch.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/Dispatch.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/Dispatch.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/Dispatch.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,21 +1,31 @@ /* Copyright (c) 2012 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM; import com.sun.jna.Pointer; import com.sun.jna.Structure; import com.sun.jna.WString; -import com.sun.jna.platform.win32.Guid.IID; import com.sun.jna.platform.win32.Guid.REFIID; import com.sun.jna.platform.win32.OaIdl.DISPID; import com.sun.jna.platform.win32.OaIdl.DISPIDByReference; @@ -99,7 +109,7 @@ * the rg disp id * @return the hresult */ - public HRESULT GetIDsOfNames(REFIID.ByValue riid, WString[] rgszNames, int cNames, + public HRESULT GetIDsOfNames(REFIID riid, WString[] rgszNames, int cNames, LCID lcid, DISPIDByReference rgDispId) { return (HRESULT) this._invokeNativeObject(5, new Object[] { this.getPointer(), riid, rgszNames, cNames, @@ -127,7 +137,7 @@ * the pu arg err * @return the hresult */ - public HRESULT Invoke(DISPID dispIdMember, REFIID.ByValue riid, LCID lcid, + public HRESULT Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS.ByReference pDispParams, VARIANT.ByReference pVarResult, EXCEPINFO.ByReference pExcepInfo, IntByReference puArgErr) { diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/DispatchListener.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/DispatchListener.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/DispatchListener.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/DispatchListener.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,104 +1,113 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM; - -import java.util.Arrays; -import java.util.List; - -import com.sun.jna.CallbackThreadInitializer; -import com.sun.jna.Native; -import com.sun.jna.Pointer; -import com.sun.jna.Structure; -import com.sun.jna.WString; -import com.sun.jna.platform.win32.Guid.REFIID; -import com.sun.jna.platform.win32.OaIdl.DISPID; -import com.sun.jna.platform.win32.OaIdl.DISPIDByReference; -import com.sun.jna.platform.win32.OaIdl.EXCEPINFO; -import com.sun.jna.platform.win32.OleAuto.DISPPARAMS; -import com.sun.jna.platform.win32.Variant.VARIANT; -import com.sun.jna.platform.win32.WinDef.LCID; -import com.sun.jna.platform.win32.WinDef.UINT; -import com.sun.jna.platform.win32.WinDef.UINTByReference; -import com.sun.jna.platform.win32.WinDef.WORD; -import com.sun.jna.platform.win32.WinNT.HRESULT; -import com.sun.jna.ptr.IntByReference; -import com.sun.jna.ptr.PointerByReference; - -public class DispatchListener extends Structure { - public DispatchListener(IDispatchCallback callback) { - this.vtbl = this.constructVTable(); - this.initVTable(callback); - super.write(); - } - public DispatchVTable.ByReference vtbl; - - @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "vtbl" }); - } - - protected DispatchVTable.ByReference constructVTable() { - return new DispatchVTable.ByReference(); - } - - protected void initVTable(final IDispatchCallback callback) { - this.vtbl.QueryInterfaceCallback = new DispatchVTable.QueryInterfaceCallback() { - @Override - public HRESULT invoke(Pointer thisPointer, REFIID.ByValue refid, PointerByReference ppvObject) { - return callback.QueryInterface(refid, ppvObject); - } - }; - this.vtbl.AddRefCallback = new DispatchVTable.AddRefCallback() { - @Override - public int invoke(Pointer thisPointer) { - return callback.AddRef(); - } - }; - this.vtbl.ReleaseCallback = new DispatchVTable.ReleaseCallback() { - @Override - public int invoke(Pointer thisPointer) { - return callback.Release(); - } - }; - this.vtbl.GetTypeInfoCountCallback = new DispatchVTable.GetTypeInfoCountCallback() { - @Override - public HRESULT invoke(Pointer thisPointer, UINTByReference pctinfo) { - return callback.GetTypeInfoCount(pctinfo); - } - }; - this.vtbl.GetTypeInfoCallback = new DispatchVTable.GetTypeInfoCallback() { - @Override - public HRESULT invoke(Pointer thisPointer, UINT iTInfo, LCID lcid, PointerByReference ppTInfo) { - return callback.GetTypeInfo(iTInfo, lcid, ppTInfo); - } - }; - this.vtbl.GetIDsOfNamesCallback = new DispatchVTable.GetIDsOfNamesCallback() { - @Override - public HRESULT invoke(Pointer thisPointer, REFIID.ByValue riid, WString[] rgszNames, int cNames, LCID lcid, - DISPIDByReference rgDispId) { - return callback.GetIDsOfNames(riid, rgszNames, cNames, lcid, rgDispId); - } - }; - this.vtbl.InvokeCallback = new DispatchVTable.InvokeCallback() { - @Override - public HRESULT invoke(Pointer thisPointer, DISPID dispIdMember, REFIID.ByValue riid, LCID lcid, WORD wFlags, - DISPPARAMS.ByReference pDispParams, VARIANT.ByReference pVarResult, EXCEPINFO.ByReference pExcepInfo, - IntByReference puArgErr) { - - return callback.Invoke(dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); - } - }; - - } - -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM; + +import java.util.List; + +import com.sun.jna.Pointer; +import com.sun.jna.Structure; +import com.sun.jna.WString; +import com.sun.jna.platform.win32.Guid.REFIID; +import com.sun.jna.platform.win32.OaIdl.DISPID; +import com.sun.jna.platform.win32.OaIdl.DISPIDByReference; +import com.sun.jna.platform.win32.OaIdl.EXCEPINFO; +import com.sun.jna.platform.win32.OleAuto.DISPPARAMS; +import com.sun.jna.platform.win32.Variant.VARIANT; +import com.sun.jna.platform.win32.WinDef.LCID; +import com.sun.jna.platform.win32.WinDef.UINT; +import com.sun.jna.platform.win32.WinDef.UINTByReference; +import com.sun.jna.platform.win32.WinDef.WORD; +import com.sun.jna.platform.win32.WinNT.HRESULT; +import com.sun.jna.ptr.IntByReference; +import com.sun.jna.ptr.PointerByReference; + +public class DispatchListener extends Structure { + public static final List FIELDS = createFieldsOrder("vtbl"); + public DispatchListener(IDispatchCallback callback) { + this.vtbl = this.constructVTable(); + this.initVTable(callback); + super.write(); + } + public DispatchVTable.ByReference vtbl; + + @Override + protected List getFieldOrder() { + return FIELDS; + } + + protected DispatchVTable.ByReference constructVTable() { + return new DispatchVTable.ByReference(); + } + + protected void initVTable(final IDispatchCallback callback) { + this.vtbl.QueryInterfaceCallback = new DispatchVTable.QueryInterfaceCallback() { + @Override + public HRESULT invoke(Pointer thisPointer, REFIID refid, PointerByReference ppvObject) { + return callback.QueryInterface(refid, ppvObject); + } + }; + this.vtbl.AddRefCallback = new DispatchVTable.AddRefCallback() { + @Override + public int invoke(Pointer thisPointer) { + return callback.AddRef(); + } + }; + this.vtbl.ReleaseCallback = new DispatchVTable.ReleaseCallback() { + @Override + public int invoke(Pointer thisPointer) { + return callback.Release(); + } + }; + this.vtbl.GetTypeInfoCountCallback = new DispatchVTable.GetTypeInfoCountCallback() { + @Override + public HRESULT invoke(Pointer thisPointer, UINTByReference pctinfo) { + return callback.GetTypeInfoCount(pctinfo); + } + }; + this.vtbl.GetTypeInfoCallback = new DispatchVTable.GetTypeInfoCallback() { + @Override + public HRESULT invoke(Pointer thisPointer, UINT iTInfo, LCID lcid, PointerByReference ppTInfo) { + return callback.GetTypeInfo(iTInfo, lcid, ppTInfo); + } + }; + this.vtbl.GetIDsOfNamesCallback = new DispatchVTable.GetIDsOfNamesCallback() { + @Override + public HRESULT invoke(Pointer thisPointer, REFIID riid, WString[] rgszNames, int cNames, LCID lcid, + DISPIDByReference rgDispId) { + return callback.GetIDsOfNames(riid, rgszNames, cNames, lcid, rgDispId); + } + }; + this.vtbl.InvokeCallback = new DispatchVTable.InvokeCallback() { + @Override + public HRESULT invoke(Pointer thisPointer, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, + DISPPARAMS.ByReference pDispParams, VARIANT.ByReference pVarResult, EXCEPINFO.ByReference pExcepInfo, + IntByReference puArgErr) { + + return callback.Invoke(dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + } + }; + + } + +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/DispatchVTable.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/DispatchVTable.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/DispatchVTable.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/DispatchVTable.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,89 +1,98 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import com.sun.jna.Pointer; -import com.sun.jna.Structure; -import com.sun.jna.WString; -import com.sun.jna.platform.win32.COM.UnknownVTable.AddRefCallback; -import com.sun.jna.platform.win32.COM.UnknownVTable.QueryInterfaceCallback; -import com.sun.jna.platform.win32.COM.UnknownVTable.ReleaseCallback; -import com.sun.jna.platform.win32.Guid.REFIID; -import com.sun.jna.platform.win32.OaIdl.DISPID; -import com.sun.jna.platform.win32.OaIdl.DISPIDByReference; -import com.sun.jna.platform.win32.OaIdl.EXCEPINFO; -import com.sun.jna.platform.win32.OleAuto.DISPPARAMS; -import com.sun.jna.platform.win32.Variant.VARIANT; -import com.sun.jna.platform.win32.WinDef.LCID; -import com.sun.jna.platform.win32.WinDef.UINT; -import com.sun.jna.platform.win32.WinDef.UINTByReference; -import com.sun.jna.platform.win32.WinDef.WORD; -import com.sun.jna.platform.win32.WinNT; -import com.sun.jna.ptr.IntByReference; -import com.sun.jna.ptr.PointerByReference; -import com.sun.jna.win32.DLLCallback; -import com.sun.jna.win32.StdCallLibrary; - -public class DispatchVTable extends Structure { - public static class ByReference extends DispatchVTable implements Structure.ByReference { - } - - public QueryInterfaceCallback QueryInterfaceCallback; - public AddRefCallback AddRefCallback; - public ReleaseCallback ReleaseCallback; - public GetTypeInfoCountCallback GetTypeInfoCountCallback; - public GetTypeInfoCallback GetTypeInfoCallback; - public GetIDsOfNamesCallback GetIDsOfNamesCallback; - public InvokeCallback InvokeCallback; - - @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "QueryInterfaceCallback", "AddRefCallback", "ReleaseCallback","GetTypeInfoCountCallback", "GetTypeInfoCallback", - "GetIDsOfNamesCallback", "InvokeCallback" }); - } - - public static interface QueryInterfaceCallback extends StdCallLibrary.StdCallCallback { - WinNT.HRESULT invoke(Pointer thisPointer, REFIID.ByValue refid, PointerByReference ppvObject); - } - - public static interface AddRefCallback extends StdCallLibrary.StdCallCallback { - int invoke(Pointer thisPointer); - } - - public static interface ReleaseCallback extends StdCallLibrary.StdCallCallback { - int invoke(Pointer thisPointer); - } - - public static interface GetTypeInfoCountCallback extends StdCallLibrary.StdCallCallback { - WinNT.HRESULT invoke(Pointer thisPointer, UINTByReference pctinfo); - } - - public static interface GetTypeInfoCallback extends StdCallLibrary.StdCallCallback { - WinNT.HRESULT invoke(Pointer thisPointer, UINT iTInfo, LCID lcid, PointerByReference ppTInfo); - } - - public static interface GetIDsOfNamesCallback extends StdCallLibrary.StdCallCallback { - WinNT.HRESULT invoke(Pointer thisPointer, REFIID.ByValue riid, WString[] rgszNames, int cNames, LCID lcid, - DISPIDByReference rgDispId); - } - - public static interface InvokeCallback extends StdCallLibrary.StdCallCallback { - WinNT.HRESULT invoke(Pointer thisPointer, DISPID dispIdMember, REFIID.ByValue riid, LCID lcid, WORD wFlags, - DISPPARAMS.ByReference pDispParams, VARIANT.ByReference pVarResult, EXCEPINFO.ByReference pExcepInfo, - IntByReference puArgErr); - } -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM; + +import java.util.List; + +import com.sun.jna.Pointer; +import com.sun.jna.Structure; +import com.sun.jna.WString; +import com.sun.jna.platform.win32.Guid.REFIID; +import com.sun.jna.platform.win32.OaIdl.DISPID; +import com.sun.jna.platform.win32.OaIdl.DISPIDByReference; +import com.sun.jna.platform.win32.OaIdl.EXCEPINFO; +import com.sun.jna.platform.win32.OleAuto.DISPPARAMS; +import com.sun.jna.platform.win32.Variant.VARIANT; +import com.sun.jna.platform.win32.WinDef.LCID; +import com.sun.jna.platform.win32.WinDef.UINT; +import com.sun.jna.platform.win32.WinDef.UINTByReference; +import com.sun.jna.platform.win32.WinDef.WORD; +import com.sun.jna.platform.win32.WinNT; +import com.sun.jna.ptr.IntByReference; +import com.sun.jna.ptr.PointerByReference; +import com.sun.jna.win32.StdCallLibrary; + +public class DispatchVTable extends Structure { + public static class ByReference extends DispatchVTable implements Structure.ByReference { + } + + public static final List FIELDS = createFieldsOrder( + "QueryInterfaceCallback", "AddRefCallback", "ReleaseCallback", + "GetTypeInfoCountCallback", "GetTypeInfoCallback", + "GetIDsOfNamesCallback", "InvokeCallback"); + + public QueryInterfaceCallback QueryInterfaceCallback; + public AddRefCallback AddRefCallback; + public ReleaseCallback ReleaseCallback; + public GetTypeInfoCountCallback GetTypeInfoCountCallback; + public GetTypeInfoCallback GetTypeInfoCallback; + public GetIDsOfNamesCallback GetIDsOfNamesCallback; + public InvokeCallback InvokeCallback; + + @Override + protected List getFieldOrder() { + return FIELDS; + } + + public static interface QueryInterfaceCallback extends StdCallLibrary.StdCallCallback { + WinNT.HRESULT invoke(Pointer thisPointer, REFIID refid, PointerByReference ppvObject); + } + + public static interface AddRefCallback extends StdCallLibrary.StdCallCallback { + int invoke(Pointer thisPointer); + } + + public static interface ReleaseCallback extends StdCallLibrary.StdCallCallback { + int invoke(Pointer thisPointer); + } + + public static interface GetTypeInfoCountCallback extends StdCallLibrary.StdCallCallback { + WinNT.HRESULT invoke(Pointer thisPointer, UINTByReference pctinfo); + } + + public static interface GetTypeInfoCallback extends StdCallLibrary.StdCallCallback { + WinNT.HRESULT invoke(Pointer thisPointer, UINT iTInfo, LCID lcid, PointerByReference ppTInfo); + } + + public static interface GetIDsOfNamesCallback extends StdCallLibrary.StdCallCallback { + WinNT.HRESULT invoke(Pointer thisPointer, REFIID riid, WString[] rgszNames, int cNames, LCID lcid, + DISPIDByReference rgDispId); + } + + public static interface InvokeCallback extends StdCallLibrary.StdCallCallback { + WinNT.HRESULT invoke(Pointer thisPointer, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, + DISPPARAMS.ByReference pDispParams, VARIANT.ByReference pVarResult, EXCEPINFO.ByReference pExcepInfo, + IntByReference puArgErr); + } +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/EnumMoniker.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/EnumMoniker.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/EnumMoniker.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/EnumMoniker.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,71 +1,82 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM; - -import com.sun.jna.Pointer; -import com.sun.jna.platform.win32.WinNT; -import com.sun.jna.platform.win32.WinDef.ULONG; -import com.sun.jna.platform.win32.WinDef.ULONGByReference; -import com.sun.jna.platform.win32.WinNT.HRESULT; -import com.sun.jna.ptr.PointerByReference; - -public class EnumMoniker extends Unknown implements IEnumMoniker { - - public EnumMoniker(Pointer pointer) { - super(pointer); - } - - // The magic number values for (vTableId) below, are worked out by - // counting the number of methods in the full interface (0 indexed), as this - // inherits IUnknown, which has 3 methods, we start here at 3. - - @Override - public HRESULT Next(ULONG celt, PointerByReference rgelt, ULONGByReference pceltFetched) { - final int vTableId = 3; - - WinNT.HRESULT hr = (WinNT.HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), celt, - rgelt, pceltFetched }, WinNT.HRESULT.class); - - return hr; - } - - @Override - public HRESULT Skip(ULONG celt) { - final int vTableId = 4; - - WinNT.HRESULT hr = (WinNT.HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), celt }, - WinNT.HRESULT.class); - - return hr; - } - - @Override - public HRESULT Reset() { - final int vTableId = 5; - - WinNT.HRESULT hr = (WinNT.HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), }, - WinNT.HRESULT.class); - - return hr; - } - - @Override - public HRESULT Clone(PointerByReference ppenum) { - final int vTableId = 6; - - WinNT.HRESULT hr = (WinNT.HRESULT) this._invokeNativeObject(vTableId, - new Object[] { this.getPointer(), ppenum }, WinNT.HRESULT.class); - - return hr; - } -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM; + +import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.WinNT; +import com.sun.jna.platform.win32.WinDef.ULONG; +import com.sun.jna.platform.win32.WinDef.ULONGByReference; +import com.sun.jna.platform.win32.WinNT.HRESULT; +import com.sun.jna.ptr.PointerByReference; + +public class EnumMoniker extends Unknown implements IEnumMoniker { + + public EnumMoniker(Pointer pointer) { + super(pointer); + } + + // The magic number values for (vTableId) below, are worked out by + // counting the number of methods in the full interface (0 indexed), as this + // inherits IUnknown, which has 3 methods, we start here at 3. + + @Override + public HRESULT Next(ULONG celt, PointerByReference rgelt, ULONGByReference pceltFetched) { + final int vTableId = 3; + + WinNT.HRESULT hr = (WinNT.HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), celt, + rgelt, pceltFetched }, WinNT.HRESULT.class); + + return hr; + } + + @Override + public HRESULT Skip(ULONG celt) { + final int vTableId = 4; + + WinNT.HRESULT hr = (WinNT.HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), celt }, + WinNT.HRESULT.class); + + return hr; + } + + @Override + public HRESULT Reset() { + final int vTableId = 5; + + WinNT.HRESULT hr = (WinNT.HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), }, + WinNT.HRESULT.class); + + return hr; + } + + @Override + public HRESULT Clone(PointerByReference ppenum) { + final int vTableId = 6; + + WinNT.HRESULT hr = (WinNT.HRESULT) this._invokeNativeObject(vTableId, + new Object[] { this.getPointer(), ppenum }, WinNT.HRESULT.class); + + return hr; + } +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/IConnectionPointContainer.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/IConnectionPointContainer.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/IConnectionPointContainer.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/IConnectionPointContainer.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,35 +1,46 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM; - -import com.sun.jna.platform.win32.Guid.IID; -import com.sun.jna.platform.win32.Guid.REFIID; -import com.sun.jna.platform.win32.WinNT.HRESULT; -import com.sun.jna.ptr.PointerByReference; - -public interface IConnectionPointContainer extends IUnknown { - public final static IID IID_IConnectionPointContainer = new IID("B196B284-BAB4-101A-B69C-00AA00341D07"); - - /** - * {@code - * HRESULT FindConnectionPoint( - * [in] REFIID riid, - * [out] IConnectionPoint **ppCP - * ); - * } - * @param riid - * @param ppCP - * @return hresult - */ - public HRESULT FindConnectionPoint( REFIID riid, PointerByReference ppCP ); -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM; + +import com.sun.jna.platform.win32.Guid.IID; +import com.sun.jna.platform.win32.Guid.REFIID; +import com.sun.jna.platform.win32.WinNT.HRESULT; +import com.sun.jna.ptr.PointerByReference; + +public interface IConnectionPointContainer extends IUnknown { + public final static IID IID_IConnectionPointContainer = new IID("B196B284-BAB4-101A-B69C-00AA00341D07"); + + /** + * {@code + * HRESULT FindConnectionPoint( + * [in] REFIID riid, + * [out] IConnectionPoint **ppCP + * ); + * } + * @param riid + * @param ppCP + * @return hresult + */ + public HRESULT FindConnectionPoint( REFIID riid, PointerByReference ppCP ); +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/IConnectionPoint.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/IConnectionPoint.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/IConnectionPoint.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/IConnectionPoint.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,66 +1,77 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM; - -import com.sun.jna.platform.win32.Guid.IID; -import com.sun.jna.platform.win32.WinDef.DWORD; -import com.sun.jna.platform.win32.WinDef.DWORDByReference; -import com.sun.jna.platform.win32.WinNT.HRESULT; -import com.sun.jna.platform.win32.WinNT; - -public interface IConnectionPoint extends IUnknown { - final static IID IID_IConnectionPoint = new IID( - "B196B286-BAB4-101A-B69C-00AA00341D07"); - - /** - * - * - * @param iid - * @return interface pointer - */ - HRESULT GetConnectionInterface(IID iid); - - /** - * - * When Advise is called, the called COM object will callback 'QueryInterface' asking for a number of - * different interfaces, for example: - * - {00000003-0000-0000-C000-000000000046} - IMarshal - * - {00000003-0000-0000-C000-000000000046} - * - {0000001B-0000-0000-C000-000000000046} - IdentityUnmarshal - * - {00000000-0000-0000-C000-000000000046} - IUnknown - * - {00000018-0000-0000-C000-000000000046} - IStdMarshalInfo - * - {00000019-0000-0000-C000-000000000046} - IExternalConnection - * - {4C1E39E1-E3E3-4296-AA86-EC938D896E92} - (some unknown private interface) - * - interface of this ConnectionPoint - * - * - * {@code - * HRESULT Advise( - * [in] IUnknown *pUnkSink, - * [out] DWORD *pdwCookie - * ); - * } - * - * @param pUnkSink - * @param pdwCookie - * @return status - */ - WinNT.HRESULT Advise(IUnknownCallback pUnkSink, DWORDByReference pdwCookie); - - /** - * - * @param dwCookie - * @return status - */ - HRESULT Unadvise(DWORD dwCookie); -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM; + +import com.sun.jna.platform.win32.Guid.IID; +import com.sun.jna.platform.win32.WinDef.DWORD; +import com.sun.jna.platform.win32.WinDef.DWORDByReference; +import com.sun.jna.platform.win32.WinNT.HRESULT; +import com.sun.jna.platform.win32.WinNT; + +public interface IConnectionPoint extends IUnknown { + final static IID IID_IConnectionPoint = new IID( + "B196B286-BAB4-101A-B69C-00AA00341D07"); + + /** + * + * + * @param iid + * @return interface pointer + */ + HRESULT GetConnectionInterface(IID iid); + + /** + * + * When Advise is called, the called COM object will callback 'QueryInterface' asking for a number of + * different interfaces, for example: + * - {00000003-0000-0000-C000-000000000046} - IMarshal + * - {00000003-0000-0000-C000-000000000046} + * - {0000001B-0000-0000-C000-000000000046} - IdentityUnmarshal + * - {00000000-0000-0000-C000-000000000046} - IUnknown + * - {00000018-0000-0000-C000-000000000046} - IStdMarshalInfo + * - {00000019-0000-0000-C000-000000000046} - IExternalConnection + * - {4C1E39E1-E3E3-4296-AA86-EC938D896E92} - (some unknown private interface) + * - interface of this ConnectionPoint + * + * + * {@code + * HRESULT Advise( + * [in] IUnknown *pUnkSink, + * [out] DWORD *pdwCookie + * ); + * } + * + * @param pUnkSink + * @param pdwCookie + * @return status + */ + WinNT.HRESULT Advise(IUnknownCallback pUnkSink, DWORDByReference pdwCookie); + + /** + * + * @param dwCookie + * @return status + */ + HRESULT Unadvise(DWORD dwCookie); +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/IDispatchCallback.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/IDispatchCallback.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/IDispatchCallback.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/IDispatchCallback.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,18 +1,29 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM; - - -public interface IDispatchCallback extends IDispatch, IUnknownCallback { - -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM; + + +public interface IDispatchCallback extends IDispatch, IUnknownCallback { + +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/IDispatch.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/IDispatch.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/IDispatch.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/IDispatch.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2012 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM; @@ -31,10 +42,10 @@ // TODO: Auto-generated Javadoc /** * Wrapper class for the IDispatch interface - * + * * IDispatch.GetTypeInfoCount 12 IDispatch.GetTypeInfo 16 * IDispatch.GetIDsOfNames 20 IDispatch.Invoke 24 - * + * * @author Tobias Wolf, wolf.tobias@gmx.net */ public interface IDispatch extends IUnknown { @@ -42,15 +53,102 @@ public final static IID IID_IDISPATCH = new IID( "00020400-0000-0000-C000-000000000046"); + /** + * Retrieves the number of type information interfaces that an object provides (either 0 or 1). + * + * @param pctinfo The number of type information interfaces provided by the object. If the object provides type information, this number is 1; otherwise the number is 0. + * @return This method can return one of these values. + * S_OK + * Success. + * E_NOTIMPL + * Failure. + */ public HRESULT GetTypeInfoCount(UINTByReference pctinfo); + /** + * Retrieves the type information for an object, which can then be used to get the type information for an interface. + * + * @param iTInfo The type information to return. Pass 0 to retrieve type information for the IDispatch implementation. + * @param lcid The locale identifier for the type information. + * An object may be able to return different type information for different languages. This is important + * for classes that support localized member names. For classes that do not support localized member names, + * this parameter can be ignored. + * @param ppTInfo The requested type information object. + * @return S_OK + * Success. + * DISP_E_BADINDEX + * The iTInfo parameter was not 0. + */ public HRESULT GetTypeInfo(UINT iTInfo, LCID lcid, PointerByReference ppTInfo); - public HRESULT GetIDsOfNames(REFIID.ByValue riid, WString[] rgszNames, int cNames, + /** + * Maps a single member and an optional set of argument names to a corresponding set of integer DISPIDs, which can be used + * on subsequent calls to Invoke. The dispatch function DispGetIDsOfNames provides a standard implementation of GetIDsOfNames. + * + * @param riid Reserved for future use. Must be IID_NULL. + * @param rgszNames The array of names to be mapped. + * @param cNames The count of the names to be mapped. + * @param lcid The locale context in which to interpret the names. + * @param rgDispId Caller-allocated array, each element of which contains an identifier (ID) corresponding to one of the names passed in + * the rgszNames array. The first element represents the member name. The subsequent elements represent each of the member's parameters. + * @return status of the operation + */ + public HRESULT GetIDsOfNames(REFIID riid, WString[] rgszNames, int cNames, LCID lcid, DISPIDByReference rgDispId); - public HRESULT Invoke(DISPID dispIdMember, REFIID.ByValue riid, LCID lcid, + /** + * Provides access to properties and methods exposed by an object. The dispatch function DispInvoke provides a standard implementation of Invoke. + * + * @param dispIdMember Identifies the member. Use GetIDsOfNames or the object's documentation to obtain the dispatch identifier. + * @param riid Reserved for future use. Must be IID_NULL. + * @param lcid The locale context in which to interpret arguments. The lcid is used by the GetIDsOfNames function, and is also + * passed to Invoke to allow the object to interpret its arguments specific to a locale. + *

    + * Applications that do not support multiple national languages can ignore this parameter. For more information, + * refer to Supporting Multiple National Languages and Exposing ActiveX Objects. + * @param wFlags Flags describing the context of the Invoke call. + * DISPATCH_METHOD + * The member is invoked as a method. If a property has the same name, both this and the DISPATCH_PROPERTYGET flag can be set. + * DISPATCH_PROPERTYGET + * The member is retrieved as a property or data member. + * DISPATCH_PROPERTYPUT + * The member is changed as a property or data member. + * DISPATCH_PROPERTYPUTREF + * The member is changed by a reference assignment, rather than a value assignment. This flag is valid only when the property accepts a reference to an object. + * @param pDispParams Pointer to a DISPPARAMS structure containing an array of arguments, an array of argument DISPIDs for named arguments, and counts for the number of elements in the arrays. + * @param pVarResult Pointer to the location where the result is to be stored, or NULL if the caller expects no result. This argument is ignored if DISPATCH_PROPERTYPUT or DISPATCH_PROPERTYPUTREF is specified. + * @param pExcepInfo Pointer to a structure that contains exception information. This structure should be filled in if DISP_E_EXCEPTION is returned. Can be NULL. + * @param puArgErr The index within rgvarg of the first argument that has an error. Arguments are stored in pDispParams->rgvarg in reverse order, + * so the first argument is the one with the highest index in the array. This parameter is returned only when the resulting return + * value is DISP_E_TYPEMISMATCH or DISP_E_PARAMNOTFOUND. This argument can be set to null. For details, see Returning Errors. + * @return This method can return one of these values. + * S_OK + * Success. + * DISP_E_BADPARAMCOUNT + * The number of elements provided to DISPPARAMS is different from the number of arguments accepted by the method or property. + * DISP_E_BADVARTYPE + * One of the arguments in DISPPARAMS is not a valid variant type. + * DISP_E_EXCEPTION + * The application needs to raise an exception. In this case, the structure passed in pexcepinfo should be filled in. + * DISP_E_MEMBERNOTFOUND + * The requested member does not exist. + * DISP_E_NONAMEDARGS + * This implementation of IDispatch does not support named arguments. + * DISP_E_OVERFLOW + * One of the arguments in DISPPARAMS could not be coerced to the specified type. + * DISP_E_PARAMNOTFOUND + * One of the parameter IDs does not correspond to a parameter on the method. In this case, puArgErr is set to the first argument that contains the error. + * DISP_E_TYPEMISMATCH + * One or more of the arguments could not be coerced. The index of the first parameter with the incorrect type within rgvarg is returned in puArgErr. + * DISP_E_UNKNOWNINTERFACE + * The interface identifier passed in riid is not IID_NULL. + * DISP_E_UNKNOWNLCID + * The member being invoked interprets string arguments according to the LCID, and the LCID is not recognized. If the LCID is not needed to interpret arguments, this error should not be returned + * DISP_E_PARAMNOTOPTIONAL + * A required parameter was omitted. + */ + public HRESULT Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS.ByReference pDispParams, VARIANT.ByReference pVarResult, EXCEPINFO.ByReference pExcepInfo, IntByReference puArgErr); diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/IEnumIDList.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/IEnumIDList.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/IEnumIDList.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/IEnumIDList.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,249 @@ +/* + * 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.COM; + +/* + * @author L W Ahonen, lwahonen@iki.fi + */ + +import com.sun.jna.Function; +import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.Guid.IID; +import com.sun.jna.platform.win32.Guid.REFIID; +import com.sun.jna.platform.win32.WinNT; +import com.sun.jna.platform.win32.WinNT.HRESULT; +import com.sun.jna.ptr.IntByReference; +import com.sun.jna.ptr.PointerByReference; + +public interface IEnumIDList { + + /** + * The interface IID for QueryInterface et al + */ + public final static IID IID_IEnumIDList = new IID( + "{000214F2-0000-0000-C000-000000000046}"); + + /** + * + * Retrieves pointers to the supported interfaces on an object. + * This method calls IUnknown::AddRef on the pointer it returns. + * + * @param riid + * The identifier of the interface being requested. + * + * @param ppvObject + * The address of a pointer variable that receives the interface pointer requested in the riid parameter. Upon successful + * return, *ppvObject contains the requested interface pointer to the object. If the object does not support the + * interface, *ppvObject is set to NULL. + * + * @return + * This method returns S_OK if the interface is supported, and E_NOINTERFACE otherwise. If ppvObject is NULL, this method returns E_POINTER. + * For any one object, a specific query for the IUnknown interface on any of the object's interfaces must always return the same pointer value. + * This enables a client to determine whether two pointers point to the same component by calling QueryInterfacewith IID_IUnknown + * and comparing the results. It is specifically not the case that queries for interfaces other than IUnknown (even the same interface + * through the same pointer) must return the same pointer value. + * + * There are four requirements for implementations of QueryInterface (In these cases, "must succeed" means "must succeed barring + * catastrophic failure."): + * The set of interfaces accessible on an object through QueryInterface must be static, not dynamic. This means that if a call + * toQueryInterface for a pointer to a specified interface succeeds the first time, it must succeed again, and if it fails + * the first time, it must fail on all subsequent queries.
 + * + * It must be reflexive: if a client holds a pointer to an interface on an object, and queries for that interface, the call must succeed.
 + * + * It must be symmetric: if a client holding a pointer to one interface queries successfully for another, a query through + * the obtained pointer for the first interface must succeed.
 + * + * It must be transitive: if a client holding a pointer to one interface queries successfully for a second, and through that + * pointer queries successfully for a third interface, a query for the first interface through the pointer for the + * third interface must succeed.
 + * Notes to Implementers + * Implementations of QueryInterface must never check ACLs. The main reason for this rule is that COM requires that an object supporting a + * particular interface always return success when queried for that interface. Another reason is that checking ACLs on QueryInterface + * does not provide any real security because any client who has access to a particular interface can hand it directly to another + * client without any calls back to the server. Also, because COM caches interface pointers, it does not callQueryInterface on + * the server every time a client does a query. + */ + HRESULT QueryInterface( + REFIID riid, + PointerByReference ppvObject); + + /** + * + * Increments the reference count for an interface on an object. This method should be called for every new copy of a pointer to an interface on an object. + * @return + * The method returns the new reference count. This value is intended to be used only for test purposes. + * + * Objects use a reference counting mechanism to ensure that the lifetime of the object includes the lifetime of references to it. You use AddRef + * to stabilize a copy of an interface pointer. It can also be called when the life of a cloned pointer must extend beyond the + * lifetime of the original pointer. The cloned pointer must be released by calling IUnknown::Release. + * + * The internal reference counter that AddRef maintains should be a 32-bit unsigned integer. + * Notes to Callers + * Call this method for every new copy of an interface pointer that you make. For example, if you are passing a copy of a pointer + * back from a method, you must call AddRef on that pointer. You must also call AddRef on a pointer before passing it as an in-out + * parameter to a method; the method will call IUnknown::Release before copying the out-value on top of it. + */ + int AddRef(); + + /** + * Decrements the reference count for an interface on an object. + * + * @return + * The method returns the new reference count. This value is intended to be used only for test purposes. + * + * When the reference count on an object reaches zero, Release must cause the interface pointer to free itself. When the released + * pointer is the only existing reference to an object (whether the object supports single or multiple interfaces), the + * implementation must free the object. + * + * Note that aggregation of objects restricts the ability to recover interface pointers. + * Notes to Callers + * Call this method when you no longer need to use an interface pointer. If you are writing a method that takes an in-out + * parameter, call Release on the pointer you are passing in before copying the out-value on top of it. + */ + int Release(); + + /* + Retrieves the specified number of item identifiers in the enumeration sequence and advances the current position by the number of items retrieved. + * @param celt + * The number of elements in the array referenced by the rgelt parameter. + * @param rgelt + * The address of a pointer to an array of ITEMIDLIST pointers that receive the item identifiers. + * The implementation must allocate these item identifiers using CoTaskMemAlloc. + * The calling application is responsible for freeing the item identifiers using CoTaskMemFree. + * The ITEMIDLIST structures returned in the array are relative to the IShellFolder being enumerated. + * @param pceltFetched + * A pointer to a value that receives a count of the item identifiers actually returned in rgelt. + * The count can be smaller than the value specified in the celt parameter. This parameter can be NULL on entry only if celt = 1, + * because in that case the method can only retrieve one (S_OK) or zero (S_FALSE) items. + * + * @return HRESULT + * Returns S_OK if the method successfully retrieved the requested celt elements. + * This method only returns S_OK if the full count of requested items are successfully retrieved. + * S_FALSE indicates that more items were requested than remained in the enumeration. + * The value pointed to by the pceltFetched parameter specifies the actual number of items retrieved. + * Note that the value will be 0 if there are no more items to retrieve. + * Returns a COM-defined error value otherwise. + * + * If this method returns a Component Object Model (COM) error code (as determined by the COMUtils.FAILED macro), + * then no entries in the rgelt array are valid on exit. If this method returns a success code (such as S_OK or S_FALSE), + * then the ULONG pointed to by the pceltFetched parameter determines how many entries in the rgelt array are valid on exit. + * + * The distinction is important in the case where celt > 1. For example, if you pass celt=10 and there are only 3 elements left, + * *pceltFetched will be 3 and the method will return S_FALSE meaning that you reached the end of the file. + * The three fetched elements will be stored into rgelt and are valid. + */ + HRESULT Next( + int celt, + PointerByReference rgelt, + IntByReference pceltFetched); + + /** + * Skips the specified number of elements in the enumeration sequence. + * @param celt + * The number of item identifiers to skip. + * @return HRESULT + * Returns S_OK if successful, or a COM-defined error value otherwise. + */ + HRESULT Skip( + int celt); + + /** + * Returns to the beginning of the enumeration sequence. + * @return HRESULT + * Returns S_OK if successful, or a COM-defined error value otherwise. + */ + + HRESULT Reset(); + + /** + * Creates a new item enumeration object with the same contents and state as the current one. + * @param ppenum + * The address of a pointer to the new enumeration object. The calling application must eventually free the new object by calling its Release member function. + * @return HRESULT + * Returns S_OK if successful, or a COM-defined error value otherwise. + */ + HRESULT Clone( + PointerByReference ppenum); + + + /* + Use this like: + + PointerByReference pbr=new PointerByReference(); + HRESULT result=SomeCOMObject.QueryInterface(IID_IEnumIDList, pbr); + if(COMUtils.SUCCEEDED(result)) IENumIDList eil=IEnumIDList.Converter.PointerToIEnumIDList(pbr); + + */ + public static class Converter { + public static IEnumIDList PointerToIEnumIDList(final PointerByReference ptr) { + final Pointer interfacePointer = ptr.getValue(); + final Pointer vTablePointer = interfacePointer.getPointer(0); + final Pointer[] vTable = new Pointer[7]; + vTablePointer.read(0, vTable, 0, 7); + return new IEnumIDList() { + + @Override + public WinNT.HRESULT QueryInterface(REFIID byValue, PointerByReference pointerByReference) { + Function f = Function.getFunction(vTable[0], Function.ALT_CONVENTION); + return new WinNT.HRESULT(f.invokeInt(new Object[]{interfacePointer, byValue, pointerByReference})); + } + + @Override + public int AddRef() { + Function f = Function.getFunction(vTable[1], Function.ALT_CONVENTION); + return f.invokeInt(new Object[]{interfacePointer}); + } + + public int Release() { + Function f = Function.getFunction(vTable[2], Function.ALT_CONVENTION); + return f.invokeInt(new Object[]{interfacePointer}); + } + + @Override + public HRESULT Next(int celt, PointerByReference rgelt, IntByReference pceltFetched) { + Function f = Function.getFunction(vTable[3], Function.ALT_CONVENTION); + return new HRESULT(f.invokeInt(new Object[]{interfacePointer, celt, rgelt, pceltFetched})); + } + + @Override + public HRESULT Skip(int celt) { + Function f = Function.getFunction(vTable[4], Function.ALT_CONVENTION); + return new HRESULT(f.invokeInt(new Object[]{interfacePointer, celt})); + } + + @Override + public HRESULT Reset() { + Function f = Function.getFunction(vTable[5], Function.ALT_CONVENTION); + return new HRESULT(f.invokeInt(new Object[]{interfacePointer})); + } + + @Override + public HRESULT Clone(PointerByReference ppenum) { + Function f = Function.getFunction(vTable[6], Function.ALT_CONVENTION); + return new HRESULT(f.invokeInt(new Object[]{interfacePointer, ppenum})); + } + }; + } + } +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/IEnumMoniker.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/IEnumMoniker.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/IEnumMoniker.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/IEnumMoniker.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,94 +1,105 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM; - -import com.sun.jna.ptr.PointerByReference; -import com.sun.jna.platform.win32.Guid.IID; -import com.sun.jna.platform.win32.WinDef.ULONG; -import com.sun.jna.platform.win32.WinDef.ULONGByReference; -import com.sun.jna.platform.win32.WinNT.HRESULT; - -/** - * Enumerates the components of a moniker or the monikers in a table of monikers. - * - * @see MSDN - * - */ -public interface IEnumMoniker extends IUnknown { - - public final static IID IID = new IID("{00000102-0000-0000-C000-000000000046}"); - - /** - * Creates a new enumerator that contains the same enumeration state as the - * current one. - * - * This method makes it possible to record a particular point in the - * enumeration sequence and then return to that point at a later time. The - * caller must release this new enumerator separately from the first - * enumerator. - * - * {@code - * HRESULT Clone( - * [out] IEnumMoniker **ppenum - * ); - * } - * - * @see MSDN - */ - HRESULT Clone(PointerByReference ppenum); - - /** - * Retrieves the specified number of items in the enumeration sequence. - * - * Note: The caller is responsible for calling Release through each pointer - * enumerated. - * - * {@code - * HRESULT Next( - * [in] ULONG celt, - * [out] IMoniker **rgelt, - * [in, out] ULONG *pceltFetched - * ); - * } - * - * @see MSDN - * - */ - HRESULT Next(ULONG celt, PointerByReference rgelt, ULONGByReference pceltFetched); - - /** - * Resets the enumeration sequence to the beginning. - * - * {@code - * HRESULT Reset(); - * } - * - * @see MSDN - * - */ - HRESULT Reset(); - - /** - * Skips over the specified number of items in the enumeration sequence. - * - * {@code - * HRESULT Skip( - * [in] ULONG celt - * ); - * } - * - * @see MSDN - * - */ - HRESULT Skip(ULONG celt); -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM; + +import com.sun.jna.ptr.PointerByReference; +import com.sun.jna.platform.win32.Guid.IID; +import com.sun.jna.platform.win32.WinDef.ULONG; +import com.sun.jna.platform.win32.WinDef.ULONGByReference; +import com.sun.jna.platform.win32.WinNT.HRESULT; + +/** + * Enumerates the components of a moniker or the monikers in a table of monikers. + * + * @see MSDN + * + */ +public interface IEnumMoniker extends IUnknown { + + public final static IID IID = new IID("{00000102-0000-0000-C000-000000000046}"); + + /** + * Creates a new enumerator that contains the same enumeration state as the + * current one. + * + * This method makes it possible to record a particular point in the + * enumeration sequence and then return to that point at a later time. The + * caller must release this new enumerator separately from the first + * enumerator. + * + * {@code + * HRESULT Clone( + * [out] IEnumMoniker **ppenum + * ); + * } + * + * @see MSDN + */ + HRESULT Clone(PointerByReference ppenum); + + /** + * Retrieves the specified number of items in the enumeration sequence. + * + * Note: The caller is responsible for calling Release through each pointer + * enumerated. + * + * {@code + * HRESULT Next( + * [in] ULONG celt, + * [out] IMoniker **rgelt, + * [in, out] ULONG *pceltFetched + * ); + * } + * + * @see MSDN + * + */ + HRESULT Next(ULONG celt, PointerByReference rgelt, ULONGByReference pceltFetched); + + /** + * Resets the enumeration sequence to the beginning. + * + * {@code + * HRESULT Reset(); + * } + * + * @see MSDN + * + */ + HRESULT Reset(); + + /** + * Skips over the specified number of items in the enumeration sequence. + * + * {@code + * HRESULT Skip( + * [in] ULONG celt + * ); + * } + * + * @see MSDN + * + */ + HRESULT Skip(ULONG celt); +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/IMoniker.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/IMoniker.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/IMoniker.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/IMoniker.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,92 +1,100 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM; - -import com.sun.jna.Pointer; -import com.sun.jna.platform.win32.WTypes.BSTRByReference; -import com.sun.jna.platform.win32.WTypes.LPSTR; -import com.sun.jna.platform.win32.WinNT.HRESULT; - - -/** - * Enables you to use a moniker object, which contains information that uniquely - * identifies a COM object. - * - * (Unimplemented, placeholder only at present) - * - * @see MSDN - * - */ -public interface IMoniker extends IPersistStream { - - /** - * Binds to the specified object. The binding process involves finding the - * object, putting it into the running state if necessary, and providing the - * caller with a pointer to a specified interface on the identified object. - * - * {@code - * HRESULT BindToObject( - * [in] IBindCtx *pbc, - * [in] IMoniker *pmkToLeft, - * [in] REFIID riidResult, - * [out] void **ppvResult - * ); - * } - * - * @see MSDN - */ - void BindToObject(); - - void BindToStorage(); - - void Reduce(); - - void ComposeWith(); - - void Enum(); - - void IsEqual(); - - void Hash(); - - void IsRunning(); - - void GetTimeOfLastChange(); - - void Inverse(); - - void CommonPrefixWith(); - - /** - * Retrieves the display name for the moniker. - * - * {@code - * HRESULT GetDisplayName( - * [in] IBindCtx *pbc, - * [in] IMoniker *pmkToLeft, - * [out] LPOLESTR *ppszDisplayName - * ); - * } - * - * @see MSDN - */ - HRESULT GetDisplayName(Pointer pbc, Pointer pmkToLeft, BSTRByReference ppszDisplayName); - - void ParseDisplayName(); - - void IsSystemMoniker(); - - void RelativePathTo(); -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM; + +import com.sun.jna.Pointer; + + +/** + * Enables you to use a moniker object, which contains information that uniquely + * identifies a COM object. + * + * (Unimplemented, placeholder only at present) + * + * @see MSDN + * + */ +public interface IMoniker extends IPersistStream { + + /** + * Binds to the specified object. The binding process involves finding the + * object, putting it into the running state if necessary, and providing the + * caller with a pointer to a specified interface on the identified object. + * + * {@code + * HRESULT BindToObject( + * [in] IBindCtx *pbc, + * [in] IMoniker *pmkToLeft, + * [in] REFIID riidResult, + * [out] void **ppvResult + * ); + * } + * + * @see MSDN + */ + void BindToObject(); + + void BindToStorage(); + + void Reduce(); + + void ComposeWith(); + + void Enum(); + + void IsEqual(); + + void Hash(); + + void IsRunning(); + + void GetTimeOfLastChange(); + + void Inverse(); + + void CommonPrefixWith(); + + /** + * Retrieves the display name for the moniker. + * + * {@code + * HRESULT GetDisplayName( + * [in] IBindCtx *pbc, + * [in] IMoniker *pmkToLeft, + * [out] LPOLESTR *ppszDisplayName + * ); + * } + * + * @see MSDN + */ + String GetDisplayName(Pointer bindContext, Pointer pmkToLeft); + + void ParseDisplayName(); + + void IsSystemMoniker(); + + void RelativePathTo(); +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/IPersist.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/IPersist.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/IPersist.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/IPersist.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,40 +1,51 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM; - -import com.sun.jna.platform.win32.Guid.CLSID; - -/** - * Provides the CLSID of an object that can be stored persistently in the - * system. Allows the object to specify which object handler to use in the - * client process, as it is used in the default implementation of marshaling. - * - * @see MSDN - * - */ -public interface IPersist extends IUnknown { - - /** - * Retrieves the class identifier (CLSID) of the object. - * - * {@code - * HRESULT GetClassID( - * [out] CLSID *pClassID - * ); - * } - * - * MSDN - */ - CLSID GetClassID(); -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM; + +import com.sun.jna.platform.win32.Guid.CLSID; + +/** + * Provides the CLSID of an object that can be stored persistently in the + * system. Allows the object to specify which object handler to use in the + * client process, as it is used in the default implementation of marshaling. + * + * @see MSDN + * + */ +public interface IPersist extends IUnknown { + + /** + * Retrieves the class identifier (CLSID) of the object. + * + * {@code + * HRESULT GetClassID( + * [out] CLSID *pClassID + * ); + * } + * + * MSDN + */ + CLSID GetClassID(); +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/IPersistStream.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/IPersistStream.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/IPersistStream.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/IPersistStream.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,57 +1,68 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM; - - -/** - * Enables the saving and loading of objects that use a simple serial stream for their storage needs. - * - * @see MSDN - * - */ -public interface IPersistStream extends IPersist { - - /** - * Determines whether an object has changed since it was last saved to its - * stream. - * - * (Unimplemented) - * - */ - boolean IsDirty(); - - /** - * Initializes an object from the stream where it was saved previously - * - * (Unimplemented) - * - */ - - void Load(IStream stm); - - /** - * Saves an object to the specified stream. - * - * (Unimplemented) - * - */ - void Save(IStream stm); - - /** - * Retrieves the size of the stream needed to save the object. - * - * (Unimplemented) - * - */ - void GetSizeMax(); -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM; + + +/** + * Enables the saving and loading of objects that use a simple serial stream for their storage needs. + * + * @see MSDN + * + */ +public interface IPersistStream extends IPersist { + + /** + * Determines whether an object has changed since it was last saved to its + * stream. + * + * (Unimplemented) + * + */ + boolean IsDirty(); + + /** + * Initializes an object from the stream where it was saved previously + * + * (Unimplemented) + * + */ + + void Load(IStream stm); + + /** + * Saves an object to the specified stream. + * + * (Unimplemented) + * + */ + void Save(IStream stm); + + /** + * Retrieves the size of the stream needed to save the object. + * + * (Unimplemented) + * + */ + void GetSizeMax(); +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/IRecordInfo.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/IRecordInfo.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/IRecordInfo.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/IRecordInfo.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2012 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/IRunningObjectTable.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/IRunningObjectTable.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/IRunningObjectTable.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/IRunningObjectTable.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,152 +1,163 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM; - -import com.sun.jna.Pointer; -import com.sun.jna.platform.win32.Guid.IID; -import com.sun.jna.platform.win32.WinBase.FILETIME; -import com.sun.jna.platform.win32.WinDef.DWORD; -import com.sun.jna.platform.win32.WinDef.DWORDByReference; -import com.sun.jna.platform.win32.WinNT.HRESULT; -import com.sun.jna.ptr.PointerByReference; - -/** - * Manages access to the running object table (ROT), a globally accessible - * look-up table on each workstation. - * - * @see MSDN - * - */ -public interface IRunningObjectTable extends IUnknown { - - public final static IID IID = new IID("{00000010-0000-0000-C000-000000000046}"); - - /** - * Creates and returns a pointer to an enumerator that can list the monikers - * of all the objects currently registered in the running object table - * (ROT). - * - * {@code - * HRESULT EnumRunning( - * [out] IEnumMoniker **ppenumMoniker - * ); - * } - * - * @see MSDN - * - */ - HRESULT EnumRunning(PointerByReference ppenumMoniker); - - /** - * - * Determines whether the object identified by the specified moniker is - * running, and if it is, retrieves a pointer to that object. - * - * {@code - * HRESULT GetObject( - * [in] IMoniker *pmkObjectName, - * [out] IUnknown **ppunkObject - * ); - * } - * - * @see MSDN - * - */ - HRESULT GetObject(Pointer pmkObjectName, PointerByReference ppunkObject); - - /** - * Retrieves the time that an object was last modified. - * - * {@code - * HRESULT GetTimeOfLastChange( - * [in] IMoniker *pmkObjectName, - * [out] FILETIME *pfiletime - * ); - * } - * - * @see MSDN - * - */ - HRESULT GetTimeOfLastChange(Pointer pmkObjectName, FILETIME.ByReference pfiletime); - - /** - * Determines whether the object identified by the specified moniker is - * currently running. - * - * {@code - * HRESULT IsRunning( - * [in] IMoniker *pmkObjectName - * ); - * } - * - * @see MSDN - * - */ - HRESULT IsRunning(Pointer pmkObjectName); - - /** - * Records the time that a running object was last modified. - * - * {@code - * HRESULT NoteChangeTime( - * [in] DWORD dwRegister, - * [in] FILETIME *pfiletime - * ); - * } - * - * @see MSDN - * - */ - HRESULT NoteChangeTime(DWORD dwRegister, FILETIME pfiletime); - - /** - * Registers an object and its identifying moniker in the running object - * table (ROT). - * - * {@code - * HRESULT Register( - * [in] DWORD grfFlags, - * [in] IUnknown *punkObject, - * [in] IMoniker *pmkObjectName, - * [out] DWORD *pdwRegister - * ); - * } - * - * @see MSDN - * - */ - HRESULT Register(DWORD grfFlags, Pointer punkObject, Pointer pmkObjectName, DWORDByReference pdwRegister); - - /** - * Removes an entry from the running object table (ROT) that was previously - * registered by a call to IRunningObjectTable.Register. - * - * {@code - * HRESULT Revoke( - * [in] DWORD dwRegister - * ); - * } - * - * @see MSDN - * - */ - HRESULT Revoke(DWORD dwRegister); -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM; + +import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.Guid.IID; +import com.sun.jna.platform.win32.WinBase.FILETIME; +import com.sun.jna.platform.win32.WinDef.DWORD; +import com.sun.jna.platform.win32.WinDef.DWORDByReference; +import com.sun.jna.platform.win32.WinNT.HRESULT; +import com.sun.jna.ptr.PointerByReference; + +/** + * Manages access to the running object table (ROT), a globally accessible + * look-up table on each workstation. + * + * @see MSDN + * + */ +public interface IRunningObjectTable extends IUnknown { + + public final static IID IID = new IID("{00000010-0000-0000-C000-000000000046}"); + + /** + * Creates and returns a pointer to an enumerator that can list the monikers + * of all the objects currently registered in the running object table + * (ROT). + * + * {@code + * HRESULT EnumRunning( + * [out] IEnumMoniker **ppenumMoniker + * ); + * } + * + * @see MSDN + * + */ + HRESULT EnumRunning(PointerByReference ppenumMoniker); + + /** + * + * Determines whether the object identified by the specified moniker is + * running, and if it is, retrieves a pointer to that object. + * + * {@code + * HRESULT GetObject( + * [in] IMoniker *pmkObjectName, + * [out] IUnknown **ppunkObject + * ); + * } + * + * @see MSDN + * + */ + HRESULT GetObject(Pointer pmkObjectName, PointerByReference ppunkObject); + + /** + * Retrieves the time that an object was last modified. + * + * {@code + * HRESULT GetTimeOfLastChange( + * [in] IMoniker *pmkObjectName, + * [out] FILETIME *pfiletime + * ); + * } + * + * @see MSDN + * + */ + HRESULT GetTimeOfLastChange(Pointer pmkObjectName, FILETIME.ByReference pfiletime); + + /** + * Determines whether the object identified by the specified moniker is + * currently running. + * + * {@code + * HRESULT IsRunning( + * [in] IMoniker *pmkObjectName + * ); + * } + * + * @see MSDN + * + */ + HRESULT IsRunning(Pointer pmkObjectName); + + /** + * Records the time that a running object was last modified. + * + * {@code + * HRESULT NoteChangeTime( + * [in] DWORD dwRegister, + * [in] FILETIME *pfiletime + * ); + * } + * + * @see MSDN + * + */ + HRESULT NoteChangeTime(DWORD dwRegister, FILETIME pfiletime); + + /** + * Registers an object and its identifying moniker in the running object + * table (ROT). + * + * {@code + * HRESULT Register( + * [in] DWORD grfFlags, + * [in] IUnknown *punkObject, + * [in] IMoniker *pmkObjectName, + * [out] DWORD *pdwRegister + * ); + * } + * + * @see MSDN + * + */ + HRESULT Register(DWORD grfFlags, Pointer punkObject, Pointer pmkObjectName, DWORDByReference pdwRegister); + + /** + * Removes an entry from the running object table (ROT) that was previously + * registered by a call to IRunningObjectTable.Register. + * + * {@code + * HRESULT Revoke( + * [in] DWORD dwRegister + * ); + * } + * + * @see MSDN + * + */ + HRESULT Revoke(DWORD dwRegister); +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/IShellFolder.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/IShellFolder.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/IShellFolder.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/IShellFolder.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,539 @@ +/* + * 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.COM; + +/* + * @author L W Ahonen, lwahonen@iki.fi + */ + +import com.sun.jna.Function; +import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.Guid.IID; +import com.sun.jna.platform.win32.Guid.REFIID; +import com.sun.jna.platform.win32.WinDef; +import com.sun.jna.platform.win32.WinNT; +import com.sun.jna.platform.win32.WinNT.HRESULT; +import com.sun.jna.ptr.IntByReference; +import com.sun.jna.ptr.PointerByReference; + +public interface IShellFolder { + + + /** + * The interface IID for QueryInterface et al + */ + public final static IID IID_ISHELLFOLDER = new IID( + "{000214E6-0000-0000-C000-000000000046}"); + + /** + * + * Retrieves pointers to the supported interfaces on an object. + * This method calls IUnknown::AddRef on the pointer it returns. + * + * @param riid + * The identifier of the interface being requested. + * + * @param ppvObject + * The address of a pointer variable that receives the interface pointer requested in the riid parameter. Upon successful + * return, *ppvObject contains the requested interface pointer to the object. If the object does not support the + * interface, *ppvObject is set to NULL. + * + * @return + * This method returns S_OK if the interface is supported, and E_NOINTERFACE otherwise. If ppvObject is NULL, this method returns E_POINTER. + * For any one object, a specific query for the IUnknown interface on any of the object's interfaces must always return the same pointer value. + * This enables a client to determine whether two pointers point to the same component by calling QueryInterfacewith IID_IUnknown + * and comparing the results. It is specifically not the case that queries for interfaces other than IUnknown (even the same interface + * through the same pointer) must return the same pointer value. + * + * There are four requirements for implementations of QueryInterface (In these cases, "must succeed" means "must succeed barring + * catastrophic failure."): + * The set of interfaces accessible on an object through QueryInterface must be static, not dynamic. This means that if a call + * toQueryInterface for a pointer to a specified interface succeeds the first time, it must succeed again, and if it fails + * the first time, it must fail on all subsequent queries.
 + * + * It must be reflexive: if a client holds a pointer to an interface on an object, and queries for that interface, the call must succeed.
 + * + * It must be symmetric: if a client holding a pointer to one interface queries successfully for another, a query through + * the obtained pointer for the first interface must succeed.
 + * + * It must be transitive: if a client holding a pointer to one interface queries successfully for a second, and through that + * pointer queries successfully for a third interface, a query for the first interface through the pointer for the + * third interface must succeed.
 + * Notes to Implementers + * Implementations of QueryInterface must never check ACLs. The main reason for this rule is that COM requires that an object supporting a + * particular interface always return success when queried for that interface. Another reason is that checking ACLs on QueryInterface + * does not provide any real security because any client who has access to a particular interface can hand it directly to another + * client without any calls back to the server. Also, because COM caches interface pointers, it does not callQueryInterface on + * the server every time a client does a query. + */ + HRESULT QueryInterface( + REFIID riid, + PointerByReference ppvObject); + + /** + * + * Increments the reference count for an interface on an object. This method should be called for every new copy of a pointer to an interface on an object. + * @return + * The method returns the new reference count. This value is intended to be used only for test purposes. + * + * Objects use a reference counting mechanism to ensure that the lifetime of the object includes the lifetime of references to it. You use AddRef + * to stabilize a copy of an interface pointer. It can also be called when the life of a cloned pointer must extend beyond the + * lifetime of the original pointer. The cloned pointer must be released by calling IUnknown::Release. + * + * The internal reference counter that AddRef maintains should be a 32-bit unsigned integer. + * Notes to Callers + * Call this method for every new copy of an interface pointer that you make. For example, if you are passing a copy of a pointer + * back from a method, you must call AddRef on that pointer. You must also call AddRef on a pointer before passing it as an in-out + * parameter to a method; the method will call IUnknown::Release before copying the out-value on top of it. + */ + int AddRef(); + + /** + * Decrements the reference count for an interface on an object. + * + * @return + * The method returns the new reference count. This value is intended to be used only for test purposes. + * + * When the reference count on an object reaches zero, Release must cause the interface pointer to free itself. When the released + * pointer is the only existing reference to an object (whether the object supports single or multiple interfaces), the + * implementation must free the object. + * + * Note that aggregation of objects restricts the ability to recover interface pointers. + * Notes to Callers + * Call this method when you no longer need to use an interface pointer. If you are writing a method that takes an in-out + * parameter, call Release on the pointer you are passing in before copying the out-value on top of it. + */ + int Release(); + + /** + * Translates the display name of a file object or a folder into an item identifier list + * + * @param hwnd + * A window handle. The client should provide a window handle if it displays a dialog or message box. Otherwise set hwnd to NULL. + * + * @param pbc + * Optional. A pointer to a bind context used to pass parameters as inputs and outputs to the parsing function. These passed parameters + * are often specific to the data source and are documented by the data source owners. For example, the file system data source accepts + * the name being parsed (as a WIN32_FIND_DATA structure), using the STR_FILE_SYS_BIND_DATA bind context parameter. + * STR_PARSE_PREFER_FOLDER_BROWSING can be passed to indicate that URLs are parsed using the file system data source when possible. + * Construct a bind context object using CreateBindCtx and populate the values using IBindCtx::RegisterObjectParam. See Bind Context + * String Keys for a complete list of these. + * + * If no data is being passed to or received from the parsing function, this value can be NULL. + * + * @param pszDisplayName + * A null-terminated Unicode string with the display name. Because each Shell folder defines its own parsing syntax, the + * form this string can take may vary. The desktop folder, for instance, accepts paths such as "C:\My Docs\My File.txt". + * It also will accept references to items in the namespace that have a GUID associated with them using the "::{GUID}" syntax. + * For example, to retrieve a fully qualified identifier list for the control panel from the desktop folder, you can use the following: + * "::{CLSID for Control Panel}\::{CLSID for printers folder}" + * + * @param pchEaten + * A pointer to a ULONG value that receives the number of characters of the display name that was parsed. If your application + * does not need this information, set pchEaten to NULL, and no value will be returned. + * + * @param ppidl + * When this method returns, contains a pointer to the PIDL for the object. The returned item identifier list specifies the item + * relative to the parsing folder. If the object associated with pszDisplayName is within the parsing folder, the returned item + * identifier list will contain only one SHITEMID structure. If the object is in a subfolder of the parsing folder, the returned + * item identifier list will contain multiple SHITEMID structures. If an error occurs, NULL is returned in this address. + * + * When it is no longer needed, it is the responsibility of the caller to free this resource by calling CoTaskMemFree. + * + * @param pdwAttributes + * The value used to query for file attributes. If not used, it should be set to NULL. To query for one or more attributes, initialize + * this parameter with the SFGAO flags that represent the attributes of interest. On return, those attributes that are true and were requested will be set. + * @return + * If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. + */ + HRESULT ParseDisplayName( + WinDef.HWND hwnd, + Pointer pbc, + String pszDisplayName, + IntByReference pchEaten, + PointerByReference ppidl, + IntByReference pdwAttributes); + + /** + * Enables a client to determine the contents of a folder by creating an item identifier enumeration object and returning its IEnumIDList interface. + * The methods supported by that interface can then be used to enumerate the folder's contents. + * + * @param hwnd + * If user input is required to perform the enumeration, this window handle should be used by the enumeration object as the parent window + * to take user input. An example would be a dialog box to ask for a password or prompt the user to insert a CD or floppy disk. + * If hwndOwner is set to NULL, the enumerator should not post any messages, and if user input is required, it should silently fail. + * + * @param grfFlags + * Flags indicating which items to include in the enumeration. For a list of possible values, see the SHCONTF enumerated type. + * + * @param ppenumIDList + * The address that receives a pointer to the IEnumIDList interface of the enumeration object created by this method. + * If an error occurs or no suitable subobjects are found, ppenumIDList is set to NULL. + * + * @return + * Returns S_OK if successful, or an error value otherwise. Some implementations may also return S_FALSE, indicating that there + * are no children matching the grfFlags that were passed in. If S_FALSE is returned, ppenumIDList is set to NULL. + * + */ + HRESULT EnumObjects( + WinDef.HWND hwnd, + int grfFlags, + PointerByReference ppenumIDList); + + /** + * + * Retrieves a handler, typically the Shell folder object that implements IShellFolder for a particular item. Optional + * parameters that control the construction of the handler are passed in the bind context. + * @param pidl + * + * The address of an ITEMIDLIST structure (PIDL) that identifies the subfolder. This value can refer to an item at any level below + * the parent folder in the namespace hierarchy. The structure contains one or more SHITEMID structures, followed by a terminating NULL. + * + * @param pbc + * + * A pointer to an IBindCtx interface on a bind context object that can be used to pass parameters to the construction of the handler. + * If this parameter is not used, set it to NULL. Because support for this parameter is optional for folder object implementations, + * some folders may not support the use of bind contexts. + * Information that can be provided in the bind context includes a BIND_OPTS structure that includes a grfMode member that indicates + * the access mode when binding to a stream handler. Other parameters can be set and discovered using IBindCtx::RegisterObjectParam + * and IBindCtx::GetObjectParam. + * + * @param riid + * The identifier of the interface to return. This may be IID_IShellFolder, IID_IStream, or any other interface that identifies a particular handler. + * + * @param ppv + * When this method returns, contains the address of a pointer to the requested interface. If an error occurs, a NULL pointer is returned at this address. + * + * @return + * If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. + * + */ + HRESULT BindToObject( + Pointer pidl, + Pointer pbc, + REFIID riid, + PointerByReference ppv); + + /** + * Requests a pointer to an object's storage interface. + * @param pidl + * The address of an ITEMIDLIST structure that identifies the subfolder relative to its parent folder. The structure must contain exactly one SHITEMID structure followed by a terminating zero. + * + * @param pbc + * The optional address of an IBindCtx interface on a bind context object to be used during this operation. If this parameter is + * not used, set it to NULL. Because support for pbc is optional for folder object implementations, some folders may not support the use of bind contexts. + * + * @param riid + * The IID of the requested storage interface. To retrieve an IStream, IStorage, or IPropertySetStorage interface pointer, set + * riid to IID_IStream, IID_IStorage, or IID_IPropertySetStorage, respectively. + * + * @param ppv + * The address that receives the interface pointer specified by riid. If an error occurs, a NULL pointer is returned in this address. + * + * @return + * If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. + * + */ + HRESULT BindToStorage( + Pointer pidl, + Pointer pbc, + REFIID riid, + PointerByReference ppv); + + /** + * Determines the relative order of two file objects or folders, given their item identifier lists. + * @param lParam + * A value that specifies how the comparison should be performed. + * The lower sixteen bits of lParam define the sorting rule. Most applications set the sorting rule to the default value of zero, indicating that the + * two items should be compared by name. The system does not define any other sorting rules. Some folder objects might allow calling applications to + * use the lower sixteen bits of lParam to specify folder-specific sorting rules. The rules and their associated lParam values are defined by the folder. + * + * When the system folder view object calls IShellFolder::CompareIDs, the lower sixteen bits of lParam are used to specify the column to be used for + * the comparison. + * The upper sixteen bits of lParam are used for flags that modify the sorting rule. The system currently defines these modifier flags. + * + * SHCIDS_ALLFIELDS + * Version 5.0. Compare all the information contained in the ITEMIDLIST structure, not just the display names. This flag is valid only for folder objects that support + * the IShellFolder2 interface. For instance, if the two items are files, the folder should compare their names, sizes, file times, attributes, and any other information + * in the structures. If this flag is set, the lower sixteen bits of lParam must be zero. + * + * SHCIDS_CANONICALONLY + * Version 5.0. When comparing by name, compare the system names but not the display names. When this flag is passed, the two items are compared by whatever criteria the + * Shell folder determines are most efficient, as long as it implements a consistent sort function. This flag is useful when comparing for equality or when the results of + * the sort are not displayed to the user. This flag cannot be combined with other flags. + * + * @param pidl1 + * A pointer to the first item's ITEMIDLIST structure. It will be relative to the folder. This ITEMIDLIST structure can contain more than one + * element; therefore, the entire structure must be compared, not just the first element. + * + * @param pidl2 + * A pointer to the second item's ITEMIDLIST structure. It will be relative to the folder. This ITEMIDLIST structure can contain more than one + * element; therefore, the entire structure must be compared, not just the first element. + * + * @return + * If this method is successful, the CODE field of the HRESULT contains one of the following values. For information regarding the extraction of + * the CODE field from the returned HRESULT, see Remarks. If this method is unsuccessful, it returns a COM error code. + * Negative + * A negative return value indicates that the first item should precede the second (pidl1 < pidl2). + * Positive + * A positive return value indicates that the first item should follow the second (pidl1 > pidl2). + * Zero + * A return value of zero indicates that the two items are the same (pidl1 = pidl2). + * Use the HRESULT_CODE macro to extract the CODE field from the HRESULT, then cast the result as a short. + * #define HRESULT_CODE(hr) ((hr) & 0xFFFF) + * + */ + HRESULT CompareIDs( + WinDef.LPARAM lParam, + Pointer pidl1, + Pointer pidl2); + + + /** + * Requests an object that can be used to obtain information from or interact with a folder object. + * + * @param hwndOwner + * A handle to the owner window. If you have implemented a custom folder view object, your folder view window should be created as a child of hwndOwner. + * + * @param riid + * A reference to the IID of the interface to retrieve through ppv, typically IID_IShellView. + * + * @param ppv + * When this method returns successfully, contains the interface pointer requested in riid. This is typically IShellView. See the Remarks section for more details. + * + * @return + * If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. + * + */ + HRESULT CreateViewObject( + WinDef.HWND hwndOwner, + REFIID riid, + PointerByReference ppv); + + /** + * Gets the attributes of one or more file or folder objects contained in the object represented by IShellFolder. + * + * @param cidl + * The number of items from which to retrieve attributes. + * + * @param apidl + * The address of an array of pointers to ITEMIDLIST structures, each of which uniquely identifies an item relative to the parent folder. + * Each ITEMIDLIST structure must contain exactly one SHITEMID structure followed by a terminating zero. + * + * @param rgfInOut + * Pointer to a single ULONG value that, on entry, contains the bitwise SFGAO attributes that the calling application is requesting. On + * exit, this value contains the requested attributes that are common to all of the specified items. + * + * @return + * If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. + * + */ + HRESULT GetAttributesOf( + int cidl, + Pointer apidl, + IntByReference rgfInOut); + + /** + * If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. + * + * @param hwndOwner + * A handle to the owner window that the client should specify if it displays a dialog box or message box. + * + * @param cidl + * The number of file objects or subfolders specified in the apidl parameter. + * + * @param apidl + * The address of an array of pointers to ITEMIDLIST structures, each of which uniquely identifies a file object or subfolder relative to + * the parent folder. Each item identifier list must contain exactly one SHITEMID structure followed by a terminating zero. + * + * @param riid + * A reference to the IID of the interface to retrieve through ppv. This can be any valid interface identifier that can be created for an + * item. The most common identifiers used by the Shell are listed in the comments at the end of this reference. + * + * @param rgfReserved + * Reserved. + * + * @param ppv + * When this method returns successfully, contains the interface pointer requested in riid. + * + * @return + * If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. + * + */ + HRESULT GetUIObjectOf( + WinDef.HWND hwndOwner, + int cidl, + Pointer apidl, + REFIID riid, + IntByReference rgfReserved, + PointerByReference ppv); + + /** + * Retrieves the display name for the specified file object or subfolder. + * + * @param pidl + * PIDL that uniquely identifies the file object or subfolder relative to the parent folder. + * + * @param flags + * Flags used to request the type of display name to return. For a list of possible values, see the SHGDNF enumerated type. + * + * @param pName + * When this method returns, contains a pointer to a STRRET structure in which to return the display name. The type of name returned in this structure can be the requested type, but the Shell folder might return a different type. + * + * @return + * If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. + * It is the caller's responsibility to free resources allocated by this function. + * + */ + HRESULT GetDisplayNameOf( + Pointer pidl, + int flags, + PointerByReference pName); + + /** + * Sets the display name of a file object or subfolder, changing the item identifier in the process. + * + * @param hwnd + * A handle to the owner window of any dialog or message box that the client displays. + * + * @param pidl + * A pointer to an ITEMIDLIST structure that uniquely identifies the file object or subfolder relative to the parent folder. + * The structure must contain exactly one SHITEMID structure followed by a terminating zero. + * + * @param pszName + * A pointer to a null-terminated string that specifies the new display name. + * + * @param uFlags + * Flags that indicate the type of name specified by the pszName parameter. For a list of possible values and combinations of values, see SHGDNF. + * + * @param ppidlOut + * Optional. If specified, the address of a pointer to an ITEMIDLIST structure that receives the ITEMIDLIST of the renamed item. The + * caller requests this value by passing a non-null ppidlOut. Implementations of IShellFolder::SetNameOf must return a pointer to the + * new ITEMIDLIST in the ppidlOut parameter. + * + * @return + * If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. + * + */ + HRESULT SetNameOf( + WinDef.HWND hwnd, + Pointer pidl, + String pszName, + int uFlags, + PointerByReference ppidlOut); + + /* + Use this like: + PointerByReference pbr=new PointerByReference(); + HRESULT result=SomeCOMObject.QueryInterface(IID_ISHELLFOLDER, pbr); + if(COMUtils.SUCCEEDED(result)) IShellFolder isf=IShellFolder.Converter.PointerToIShellFolder(pbr); + */ + + public static class Converter + { + public static IShellFolder PointerToIShellFolder(final PointerByReference ptr) + { + final Pointer interfacePointer = ptr.getValue(); + final Pointer vTablePointer = interfacePointer.getPointer(0); + final Pointer[] vTable = new Pointer[13]; + vTablePointer.read(0, vTable, 0, 13); + return new IShellFolder() { + + @Override + public WinNT.HRESULT QueryInterface(REFIID byValue, PointerByReference pointerByReference) { + Function f = Function.getFunction(vTable[0], Function.ALT_CONVENTION); + return new WinNT.HRESULT(f.invokeInt(new Object[]{interfacePointer, byValue, pointerByReference})); + } + + @Override + public int AddRef() { + Function f = Function.getFunction(vTable[1], Function.ALT_CONVENTION); + return f.invokeInt(new Object[]{interfacePointer}); + } + + public int Release() { + Function f = Function.getFunction(vTable[2], Function.ALT_CONVENTION); + return f.invokeInt(new Object[]{interfacePointer}); + } + + @Override + public WinNT.HRESULT ParseDisplayName(WinDef.HWND hwnd, Pointer pbc, String pszDisplayName, IntByReference pchEaten, PointerByReference ppidl, IntByReference pdwAttributes) { + Function f = Function.getFunction(vTable[3], Function.ALT_CONVENTION); + return new WinNT.HRESULT(f.invokeInt(new Object[]{interfacePointer, hwnd, pbc, pszDisplayName, pchEaten, ppidl, pdwAttributes})); + } + + @Override + public WinNT.HRESULT EnumObjects(WinDef.HWND hwnd, int grfFlags, PointerByReference ppenumIDList) { + Function f = Function.getFunction(vTable[4], Function.ALT_CONVENTION); + return new WinNT.HRESULT( f.invokeInt(new Object[]{interfacePointer, hwnd, grfFlags, ppenumIDList})); + } + + public WinNT.HRESULT BindToObject(Pointer pidl, Pointer pbc, REFIID riid, PointerByReference ppv) { + Function f = Function.getFunction(vTable[5], Function.ALT_CONVENTION); + return new WinNT.HRESULT( f.invokeInt(new Object[]{interfacePointer, pidl, pbc, riid, ppv})); + } + + @Override + public HRESULT BindToStorage(Pointer pidl, Pointer pbc, REFIID riid, PointerByReference ppv) { + Function f = Function.getFunction(vTable[6], Function.ALT_CONVENTION); + return new WinNT.HRESULT( f.invokeInt(new Object[]{interfacePointer, pidl, pbc, riid, ppv})); + } + + @Override + public HRESULT CompareIDs(WinDef.LPARAM lParam, Pointer pidl1, Pointer pidl2) { + Function f = Function.getFunction(vTable[7], Function.ALT_CONVENTION); + return new WinNT.HRESULT( f.invokeInt(new Object[]{interfacePointer, lParam, pidl1, pidl2})); + } + + @Override + public HRESULT CreateViewObject(WinDef.HWND hwndOwner, REFIID riid, PointerByReference ppv) { + Function f = Function.getFunction(vTable[8], Function.ALT_CONVENTION); + return new WinNT.HRESULT( f.invokeInt(new Object[]{interfacePointer, hwndOwner, riid, ppv})); + } + + @Override + public HRESULT GetAttributesOf(int cidl, Pointer apidl, IntByReference rgfInOut) { + Function f = Function.getFunction(vTable[9], Function.ALT_CONVENTION); + return new WinNT.HRESULT( f.invokeInt(new Object[]{interfacePointer, cidl, apidl, rgfInOut})); + } + + @Override + public HRESULT GetUIObjectOf(WinDef.HWND hwndOwner, int cidl, Pointer apidl, REFIID riid, IntByReference rgfReserved, PointerByReference ppv) { + Function f = Function.getFunction(vTable[10], Function.ALT_CONVENTION); + return new WinNT.HRESULT( f.invokeInt(new Object[]{interfacePointer, hwndOwner, cidl, apidl, riid, rgfReserved, ppv})); + } + + public WinNT.HRESULT GetDisplayNameOf(Pointer pidl, int flags, PointerByReference pName){ + Function f = Function.getFunction(vTable[11], Function.ALT_CONVENTION); + return new WinNT.HRESULT( f.invokeInt(new Object[]{interfacePointer, pidl, flags, pName})); + } + + @Override + public HRESULT SetNameOf(WinDef.HWND hwnd, Pointer pidl, String pszName, int uFlags, PointerByReference ppidlOut) { + Function f = Function.getFunction(vTable[12], Function.ALT_CONVENTION); + return new WinNT.HRESULT( f.invokeInt(new Object[]{interfacePointer, hwnd, pidl, pszName, uFlags, ppidlOut})); + } + }; + } + } +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/IStream.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/IStream.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/IStream.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/IStream.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,29 +1,40 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM; - -/** - * The IStream interface lets you read and write data to stream objects. Stream - * objects contain the data in a structured storage object, where storages - * provide the structure. Simple data can be written directly to a stream but, - * most frequently, streams are elements nested within a storage object. They - * are similar to standard files. - * - * (Place holder, incomplete) - * - * @see MSDN - * - */ -public interface IStream { - -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM; + +/** + * The IStream interface lets you read and write data to stream objects. Stream + * objects contain the data in a structured storage object, where storages + * provide the structure. Simple data can be written directly to a stream but, + * most frequently, streams are elements nested within a storage object. They + * are similar to standard files. + * + * (Place holder, incomplete) + * + * @see MSDN + * + */ +public interface IStream { + +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/ITypeComp.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/ITypeComp.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/ITypeComp.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/ITypeComp.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2012 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/ITypeInfo.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/ITypeInfo.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/ITypeInfo.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/ITypeInfo.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2012 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM; @@ -17,7 +28,6 @@ import com.sun.jna.platform.win32.OaIdl.FUNCDESC; import com.sun.jna.platform.win32.OaIdl.HREFTYPE; import com.sun.jna.platform.win32.OaIdl.HREFTYPEByReference; -import com.sun.jna.platform.win32.OaIdl.HREFTYPEByReference; import com.sun.jna.platform.win32.OaIdl.INVOKEKIND; import com.sun.jna.platform.win32.OaIdl.MEMBERID; import com.sun.jna.platform.win32.OaIdl.TYPEATTR; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/ITypeLib.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/ITypeLib.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/ITypeLib.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/ITypeLib.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,17 +1,29 @@ /* Copyright (c) 2012 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM; +import com.sun.jna.Pointer; import com.sun.jna.platform.win32.Guid.GUID; import com.sun.jna.platform.win32.OaIdl.MEMBERID; import com.sun.jna.platform.win32.OaIdl.TLIBATTR; @@ -69,9 +81,9 @@ public HRESULT FindName( /* [annotation][out][in] */ - BSTRByReference szNameBuf, + LPOLESTR szNameBuf, /* [in] */ULONG lHashVal, - /* [length_is][size_is][out] */ITypeInfo[] ppTInfo, + /* [length_is][size_is][out] */Pointer[] ppTInfo, /* [length_is][size_is][out] */MEMBERID[] rgMemId, /* [out][in] */USHORTByReference pcFound); diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/IUnknownCallback.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/IUnknownCallback.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/IUnknownCallback.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/IUnknownCallback.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,19 +1,30 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM; - -import com.sun.jna.Pointer; - -public interface IUnknownCallback extends IUnknown { - Pointer getPointer(); -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM; + +import com.sun.jna.Pointer; + +public interface IUnknownCallback extends IUnknown { + Pointer getPointer(); +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/IUnknown.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/IUnknown.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/IUnknown.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/IUnknown.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2012 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM; @@ -32,7 +43,7 @@ public final static IID IID_IUNKNOWN = new IID( "{00000000-0000-0000-C000-000000000046}"); - public HRESULT QueryInterface(REFIID.ByValue riid, PointerByReference ppvObject); + public HRESULT QueryInterface(REFIID riid, PointerByReference ppvObject); public int AddRef(); diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/Moniker.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/Moniker.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/Moniker.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/Moniker.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,173 +1,196 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM; - -import com.sun.jna.Pointer; -import com.sun.jna.Structure; -import com.sun.jna.WString; -import com.sun.jna.platform.win32.WTypes.BSTRByReference; -import com.sun.jna.platform.win32.WTypes.LPSTR; -import com.sun.jna.platform.win32.WinNT; -import com.sun.jna.platform.win32.Guid.CLSID; -import com.sun.jna.platform.win32.WinNT.HRESULT; - -public class Moniker extends Unknown implements IMoniker { - - public static class ByReference extends Moniker implements Structure.ByReference { - } - - public Moniker() { - } - - public Moniker(Pointer pointer) { - super(pointer); - } - - // There are 8 virtual methods in the ancestors of this class/interfaces - static final int vTableIdStart = 7; - - @Override - public void BindToObject() { - final int vTableId = vTableIdStart + 1; - - throw new UnsupportedOperationException(); - } - - @Override - public void BindToStorage() { - final int vTableId = vTableIdStart + 2; - - throw new UnsupportedOperationException(); - } - - @Override - public void Reduce() { - final int vTableId = vTableIdStart + 3; - - throw new UnsupportedOperationException(); - } - - @Override - public void ComposeWith() { - final int vTableId = vTableIdStart + 4; - - throw new UnsupportedOperationException(); - } - - @Override - public void Enum() { - final int vTableId = vTableIdStart + 5; - - throw new UnsupportedOperationException(); - } - - @Override - public void IsEqual() { - final int vTableId = vTableIdStart + 6; - - throw new UnsupportedOperationException(); - } - - @Override - public void Hash() { - final int vTableId = vTableIdStart + 7; - - throw new UnsupportedOperationException(); - } - - @Override - public void IsRunning() { - final int vTableId = vTableIdStart + 8; - - throw new UnsupportedOperationException(); - } - - @Override - public void GetTimeOfLastChange() { - final int vTableId = vTableIdStart + 9; - - throw new UnsupportedOperationException(); - } - - @Override - public void Inverse() { - final int vTableId = vTableIdStart + 10; - - throw new UnsupportedOperationException(); - } - - @Override - public void CommonPrefixWith() { - final int vTableId = vTableIdStart + 11; - - throw new UnsupportedOperationException(); - } - - @Override - public void RelativePathTo() { - final int vTableId = vTableIdStart + 12; - - throw new UnsupportedOperationException(); - } - - @Override - public HRESULT GetDisplayName(Pointer pbc, Pointer pmkToLeft, BSTRByReference ppszDisplayName) { - final int vTableId = vTableIdStart + 13; - - WinNT.HRESULT hr = (WinNT.HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), pbc, - pmkToLeft, ppszDisplayName }, WinNT.HRESULT.class); - - return hr; - } - - @Override - public void ParseDisplayName() { - final int vTableId = vTableIdStart + 14; - - throw new UnsupportedOperationException(); - } - - @Override - public void IsSystemMoniker() { - final int vTableId = vTableIdStart + 15; - - throw new UnsupportedOperationException(); - } - - // ------------------------ IPersistStream ---------------------------- - @Override - public boolean IsDirty() { - throw new UnsupportedOperationException(); - } - - @Override - public void Load(IStream stm) { - throw new UnsupportedOperationException(); - } - - @Override - public void Save(IStream stm) { - throw new UnsupportedOperationException(); - } - - @Override - public void GetSizeMax() { - throw new UnsupportedOperationException(); - } - - @Override - public CLSID GetClassID() { - throw new UnsupportedOperationException(); - } - -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM; + +import com.sun.jna.Pointer; +import com.sun.jna.Structure; +import com.sun.jna.platform.win32.WinNT; +import com.sun.jna.platform.win32.Guid.CLSID; +import com.sun.jna.platform.win32.Ole32; +import com.sun.jna.platform.win32.WTypes; +import com.sun.jna.ptr.PointerByReference; + +public class Moniker extends Unknown implements IMoniker { + + public static class ByReference extends Moniker implements Structure.ByReference { + } + + public Moniker() { + } + + public Moniker(Pointer pointer) { + super(pointer); + } + + // There are 8 virtual methods in the ancestors of this class/interfaces + static final int vTableIdStart = 7; + + @Override + public void BindToObject() { + final int vTableId = vTableIdStart + 1; + + throw new UnsupportedOperationException(); + } + + @Override + public void BindToStorage() { + final int vTableId = vTableIdStart + 2; + + throw new UnsupportedOperationException(); + } + + @Override + public void Reduce() { + final int vTableId = vTableIdStart + 3; + + throw new UnsupportedOperationException(); + } + + @Override + public void ComposeWith() { + final int vTableId = vTableIdStart + 4; + + throw new UnsupportedOperationException(); + } + + @Override + public void Enum() { + final int vTableId = vTableIdStart + 5; + + throw new UnsupportedOperationException(); + } + + @Override + public void IsEqual() { + final int vTableId = vTableIdStart + 6; + + throw new UnsupportedOperationException(); + } + + @Override + public void Hash() { + final int vTableId = vTableIdStart + 7; + + throw new UnsupportedOperationException(); + } + + @Override + public void IsRunning() { + final int vTableId = vTableIdStart + 8; + + throw new UnsupportedOperationException(); + } + + @Override + public void GetTimeOfLastChange() { + final int vTableId = vTableIdStart + 9; + + throw new UnsupportedOperationException(); + } + + @Override + public void Inverse() { + final int vTableId = vTableIdStart + 10; + + throw new UnsupportedOperationException(); + } + + @Override + public void CommonPrefixWith() { + final int vTableId = vTableIdStart + 11; + + throw new UnsupportedOperationException(); + } + + @Override + public void RelativePathTo() { + final int vTableId = vTableIdStart + 12; + + throw new UnsupportedOperationException(); + } + + @Override + public String GetDisplayName(Pointer pbc, Pointer pmkToLeft) { + final int vTableId = vTableIdStart + 13; + + PointerByReference ppszDisplayNameRef = new PointerByReference(); + + WinNT.HRESULT hr = (WinNT.HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), pbc, + pmkToLeft, ppszDisplayNameRef }, WinNT.HRESULT.class); + + COMUtils.checkRC(hr); + + Pointer ppszDisplayName = ppszDisplayNameRef.getValue(); + if(ppszDisplayName == null) { + return null; + } + + WTypes.LPOLESTR oleStr = new WTypes.LPOLESTR(ppszDisplayName); + String name = oleStr.getValue(); + Ole32.INSTANCE.CoTaskMemFree(ppszDisplayName); + + return name; + } + + @Override + public void ParseDisplayName() { + final int vTableId = vTableIdStart + 14; + + throw new UnsupportedOperationException(); + } + + @Override + public void IsSystemMoniker() { + final int vTableId = vTableIdStart + 15; + + throw new UnsupportedOperationException(); + } + + // ------------------------ IPersistStream ---------------------------- + @Override + public boolean IsDirty() { + throw new UnsupportedOperationException(); + } + + @Override + public void Load(IStream stm) { + throw new UnsupportedOperationException(); + } + + @Override + public void Save(IStream stm) { + throw new UnsupportedOperationException(); + } + + @Override + public void GetSizeMax() { + throw new UnsupportedOperationException(); + } + + @Override + public CLSID GetClassID() { + throw new UnsupportedOperationException(); + } + +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/RecordInfo.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/RecordInfo.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/RecordInfo.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/RecordInfo.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2012 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/RunningObjectTable.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/RunningObjectTable.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/RunningObjectTable.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/RunningObjectTable.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,110 +1,121 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM; - -import com.sun.jna.Pointer; -import com.sun.jna.Structure; -import com.sun.jna.platform.win32.WinBase.FILETIME; -import com.sun.jna.platform.win32.WinDef.DWORD; -import com.sun.jna.platform.win32.WinDef.DWORDByReference; -import com.sun.jna.platform.win32.WinNT; -import com.sun.jna.platform.win32.WinNT.HRESULT; -import com.sun.jna.ptr.PointerByReference; - -public class RunningObjectTable extends Unknown implements IRunningObjectTable { - - public static class ByReference extends RunningObjectTable implements Structure.ByReference { - } - - public RunningObjectTable() { - } - - public RunningObjectTable(Pointer pointer) { - super(pointer); - } - - // The magic number values for (vTableId) below, are worked out by - // counting the number of methods in the full interface (0 indexed), as this - // inherits IUnknown, which has 3 methods, we start here at 3. - - @Override - public HRESULT Register(DWORD grfFlags, Pointer punkObject, Pointer pmkObjectName, DWORDByReference pdwRegister) { - final int vTableId = 3; - - WinNT.HRESULT hr = (WinNT.HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), - grfFlags, punkObject, pmkObjectName, pdwRegister }, WinNT.HRESULT.class); - - return hr; - } - - @Override - public HRESULT Revoke(DWORD dwRegister) { - final int vTableId = 4; - - WinNT.HRESULT hr = (WinNT.HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), - dwRegister }, WinNT.HRESULT.class); - - return hr; - } - - @Override - public HRESULT IsRunning(Pointer pmkObjectName) { - final int vTableId = 5; - - WinNT.HRESULT hr = (WinNT.HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), - pmkObjectName }, WinNT.HRESULT.class); - - return hr; - } - - @Override - public HRESULT GetObject(Pointer pmkObjectName, PointerByReference ppunkObject) { - final int vTableId = 6; - - WinNT.HRESULT hr = (WinNT.HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), - pmkObjectName, ppunkObject }, WinNT.HRESULT.class); - - return hr; - } - - @Override - public HRESULT NoteChangeTime(DWORD dwRegister, FILETIME pfiletime) { - final int vTableId = 7; - - WinNT.HRESULT hr = (WinNT.HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), - dwRegister, pfiletime }, WinNT.HRESULT.class); - - return hr; - } - - @Override - public HRESULT GetTimeOfLastChange(Pointer pmkObjectName, FILETIME.ByReference pfiletime) { - final int vTableId = 8; - - WinNT.HRESULT hr = (WinNT.HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), - pmkObjectName, pfiletime }, WinNT.HRESULT.class); - - return hr; - } - - @Override - public HRESULT EnumRunning(PointerByReference ppenumMoniker) { - final int vTableId = 9; - - WinNT.HRESULT hr = (WinNT.HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), - ppenumMoniker }, WinNT.HRESULT.class); - - return hr; - } - -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM; + +import com.sun.jna.Pointer; +import com.sun.jna.Structure; +import com.sun.jna.platform.win32.WinBase.FILETIME; +import com.sun.jna.platform.win32.WinDef.DWORD; +import com.sun.jna.platform.win32.WinDef.DWORDByReference; +import com.sun.jna.platform.win32.WinNT; +import com.sun.jna.platform.win32.WinNT.HRESULT; +import com.sun.jna.ptr.PointerByReference; + +public class RunningObjectTable extends Unknown implements IRunningObjectTable { + + public static class ByReference extends RunningObjectTable implements Structure.ByReference { + } + + public RunningObjectTable() { + } + + public RunningObjectTable(Pointer pointer) { + super(pointer); + } + + // The magic number values for (vTableId) below, are worked out by + // counting the number of methods in the full interface (0 indexed), as this + // inherits IUnknown, which has 3 methods, we start here at 3. + + @Override + public HRESULT Register(DWORD grfFlags, Pointer punkObject, Pointer pmkObjectName, DWORDByReference pdwRegister) { + final int vTableId = 3; + + WinNT.HRESULT hr = (WinNT.HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), + grfFlags, punkObject, pmkObjectName, pdwRegister }, WinNT.HRESULT.class); + + return hr; + } + + @Override + public HRESULT Revoke(DWORD dwRegister) { + final int vTableId = 4; + + WinNT.HRESULT hr = (WinNT.HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), + dwRegister }, WinNT.HRESULT.class); + + return hr; + } + + @Override + public HRESULT IsRunning(Pointer pmkObjectName) { + final int vTableId = 5; + + WinNT.HRESULT hr = (WinNT.HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), + pmkObjectName }, WinNT.HRESULT.class); + + return hr; + } + + @Override + public HRESULT GetObject(Pointer pmkObjectName, PointerByReference ppunkObject) { + final int vTableId = 6; + + WinNT.HRESULT hr = (WinNT.HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), + pmkObjectName, ppunkObject }, WinNT.HRESULT.class); + + return hr; + } + + @Override + public HRESULT NoteChangeTime(DWORD dwRegister, FILETIME pfiletime) { + final int vTableId = 7; + + WinNT.HRESULT hr = (WinNT.HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), + dwRegister, pfiletime }, WinNT.HRESULT.class); + + return hr; + } + + @Override + public HRESULT GetTimeOfLastChange(Pointer pmkObjectName, FILETIME.ByReference pfiletime) { + final int vTableId = 8; + + WinNT.HRESULT hr = (WinNT.HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), + pmkObjectName, pfiletime }, WinNT.HRESULT.class); + + return hr; + } + + @Override + public HRESULT EnumRunning(PointerByReference ppenumMoniker) { + final int vTableId = 9; + + WinNT.HRESULT hr = (WinNT.HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), + ppenumMoniker }, WinNT.HRESULT.class); + + return hr; + } + +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbAbstractMethod.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbAbstractMethod.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbAbstractMethod.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbAbstractMethod.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2013 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM.tlb.imp; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbBase.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbBase.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbBase.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbBase.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2013 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM.tlb.imp; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbCmdlineArgs.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbCmdlineArgs.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbCmdlineArgs.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbCmdlineArgs.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,21 +1,32 @@ /* Copyright (c) 2013 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM.tlb.imp; import java.util.Hashtable; -public class TlbCmdlineArgs extends Hashtable implements - TlbConst { +public class TlbCmdlineArgs extends Hashtable implements TlbConst { + private static final long serialVersionUID = 1L; public TlbCmdlineArgs(String[] args) { this.readCmdArgs(args); @@ -23,7 +34,7 @@ public int getIntParam(String key) { String param = this.getRequiredParam(key); - return new Integer(param).intValue(); + return Integer.parseInt(param); } public String getParam(String key) { @@ -70,7 +81,7 @@ else return BINDING_MODE_VTABLE; } - + public void showCmdHelp() { String helpStr = "usage: TlbImp [-tlb.id -tlb.major.version -tlb.minor.version] [-tlb.file] [-bind.mode vTable, dispId] [-output.dir]" + CRCR diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbCoClass.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbCoClass.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbCoClass.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbCoClass.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2013 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM.tlb.imp; @@ -97,21 +108,18 @@ FUNCDESC funcDesc = typeInfoUtil.getFuncDesc(i); TlbAbstractMethod method = null; - if (funcDesc.invkind.equals(INVOKEKIND.INVOKE_FUNC)) { - if(this.isVTableMode()) + if (funcDesc.invkind.value == INVOKEKIND.INVOKE_FUNC.value) { + if(this.isVTableMode()) { method = new TlbFunctionVTable(i, index, typeLibUtil, funcDesc, typeInfoUtil); - else + } else { method = new TlbFunctionDispId(i, index, typeLibUtil, funcDesc, typeInfoUtil); - } else if (funcDesc.invkind.equals(INVOKEKIND.INVOKE_PROPERTYGET)) { - method = new TlbPropertyGet(i, index, typeLibUtil, funcDesc, - typeInfoUtil); - } else if (funcDesc.invkind.equals(INVOKEKIND.INVOKE_PROPERTYPUT)) { - method = new TlbPropertyPut(i, index, typeLibUtil, funcDesc, - typeInfoUtil); - } else if (funcDesc.invkind - .equals(INVOKEKIND.INVOKE_PROPERTYPUTREF)) { - method = new TlbPropertyPut(i, index, typeLibUtil, funcDesc, - typeInfoUtil); + } + } else if (funcDesc.invkind.value == INVOKEKIND.INVOKE_PROPERTYGET.value) { + method = new TlbPropertyGet(i, index, typeLibUtil, funcDesc, typeInfoUtil); + } else if (funcDesc.invkind.value == INVOKEKIND.INVOKE_PROPERTYPUT.value) { + method = new TlbPropertyPut(i, index, typeLibUtil, funcDesc, typeInfoUtil); + } else if (funcDesc.invkind.value == INVOKEKIND.INVOKE_PROPERTYPUTREF.value) { + method = new TlbPropertyPut(i, index, typeLibUtil, funcDesc, typeInfoUtil); } if(!isReservedMethod(method.getMethodName())) diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbConst.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbConst.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbConst.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbConst.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2013 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM.tlb.imp; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbDispInterface.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbDispInterface.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbDispInterface.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbDispInterface.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,24 +1,32 @@ /* Copyright (c) 2013 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM.tlb.imp; import com.sun.jna.platform.win32.OaIdl.FUNCDESC; -import com.sun.jna.platform.win32.OaIdl.HREFTYPE; import com.sun.jna.platform.win32.OaIdl.INVOKEKIND; import com.sun.jna.platform.win32.OaIdl.MEMBERID; import com.sun.jna.platform.win32.OaIdl.TYPEATTR; -import com.sun.jna.platform.win32.WinDef.WORD; -import com.sun.jna.platform.win32.COM.ITypeInfo; import com.sun.jna.platform.win32.COM.TypeInfoUtil; import com.sun.jna.platform.win32.COM.TypeInfoUtil.TypeInfoDoc; import com.sun.jna.platform.win32.COM.TypeLibUtil; @@ -76,27 +84,21 @@ TlbAbstractMethod method = null; if (!isReservedMethod(methodName)) { - if (funcDesc.invkind.equals(INVOKEKIND.INVOKE_FUNC)) { - method = new TlbFunctionStub(index, typeLibUtil, funcDesc, - typeInfoUtil); - } else if (funcDesc.invkind - .equals(INVOKEKIND.INVOKE_PROPERTYGET)) { - method = new TlbPropertyGetStub(index, typeLibUtil, - funcDesc, typeInfoUtil); - } else if (funcDesc.invkind - .equals(INVOKEKIND.INVOKE_PROPERTYPUT)) { - method = new TlbPropertyPutStub(index, typeLibUtil, - funcDesc, typeInfoUtil); - } else if (funcDesc.invkind - .equals(INVOKEKIND.INVOKE_PROPERTYPUTREF)) { - method = new TlbPropertyPutStub(index, typeLibUtil, - funcDesc, typeInfoUtil); + if (funcDesc.invkind.value == INVOKEKIND.INVOKE_FUNC.value) { + method = new TlbFunctionStub(index, typeLibUtil, funcDesc, typeInfoUtil); + } else if (funcDesc.invkind.value == INVOKEKIND.INVOKE_PROPERTYGET.value) { + method = new TlbPropertyGetStub(index, typeLibUtil, funcDesc, typeInfoUtil); + } else if (funcDesc.invkind.value == INVOKEKIND.INVOKE_PROPERTYPUT.value) { + method = new TlbPropertyPutStub(index, typeLibUtil, funcDesc, typeInfoUtil); + } else if (funcDesc.invkind.value == INVOKEKIND.INVOKE_PROPERTYPUTREF.value) { + method = new TlbPropertyPutStub(index, typeLibUtil, funcDesc, typeInfoUtil); } this.content += method.getClassBuffer(); - if (i < cFuncs - 1) + if (i < cFuncs - 1) { this.content += CR; + } } // Release our function description stuff diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbEnum.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbEnum.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbEnum.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbEnum.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2013 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM.tlb.imp; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbFunctionDispId.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbFunctionDispId.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbFunctionDispId.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbFunctionDispId.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2013 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM.tlb.imp; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbFunctionStub.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbFunctionStub.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbFunctionStub.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbFunctionStub.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2013 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM.tlb.imp; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbFunctionVTable.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbFunctionVTable.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbFunctionVTable.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbFunctionVTable.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2013 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM.tlb.imp; @@ -20,14 +31,14 @@ // TODO: Auto-generated Javadoc /** * The Class TlbFunction. - * + * * @author Tobias Wolf, wolf.tobias@gmx.net */ public class TlbFunctionVTable extends TlbAbstractMethod { /** * Instantiates a new tlb function. - * + * * @param index * the index * @param typeLibUtil @@ -71,11 +82,6 @@ this.replaceVariable("functionCount", String.valueOf(count)); } - /* - * (non-Javadoc) - * - * @see com.sun.jna.platform.win32.COM.tlb.imp.TlbBase#getClassTemplate() - */ @Override protected String getClassTemplate() { return "com/sun/jna/platform/win32/COM/tlb/imp/TlbFunctionVTable.template"; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbInterface.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbInterface.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbInterface.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbInterface.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2013 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM.tlb.imp; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbParameterNotFoundException.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbParameterNotFoundException.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbParameterNotFoundException.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbParameterNotFoundException.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,20 +1,33 @@ /* Copyright (c) 2013 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM.tlb.imp; public class TlbParameterNotFoundException extends RuntimeException { + private static final long serialVersionUID = 1L; public TlbParameterNotFoundException() { + super(); } public TlbParameterNotFoundException(String msg) { diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbPropertyGet.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbPropertyGet.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbPropertyGet.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbPropertyGet.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2013 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM.tlb.imp; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbPropertyGetStub.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbPropertyGetStub.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbPropertyGetStub.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbPropertyGetStub.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2013 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM.tlb.imp; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbPropertyPut.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbPropertyPut.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbPropertyPut.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbPropertyPut.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2013 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM.tlb.imp; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbPropertyPutStub.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbPropertyPutStub.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbPropertyPutStub.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/imp/TlbPropertyPutStub.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2013 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM.tlb.imp; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/TlbImp.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/TlbImp.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/TlbImp.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/tlb/TlbImp.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2013 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM.tlb; @@ -98,9 +109,9 @@ if (typekind.value == TYPEKIND.TKIND_ENUM) { this.createCOMEnum(i, this.getPackageName(), typeLibUtil); } else if (typekind.value == TYPEKIND.TKIND_RECORD) { - this.logInfo("'TKIND_RECORD' objects are currently not supported!"); + TlbImp.logInfo("'TKIND_RECORD' objects are currently not supported!"); } else if (typekind.value == TYPEKIND.TKIND_MODULE) { - this.logInfo("'TKIND_MODULE' objects are currently not supported!"); + TlbImp.logInfo("'TKIND_MODULE' objects are currently not supported!"); } else if (typekind.value == TYPEKIND.TKIND_INTERFACE) { this.createCOMInterface(i, this.getPackageName(), typeLibUtil); @@ -111,9 +122,9 @@ this.createCOMCoClass(i, this.getPackageName(), typeLibUtil, bindingMode); } else if (typekind.value == TYPEKIND.TKIND_ALIAS) { - this.logInfo("'TKIND_ALIAS' objects are currently not supported!"); + TlbImp.logInfo("'TKIND_ALIAS' objects are currently not supported!"); } else if (typekind.value == TYPEKIND.TKIND_UNION) { - this.logInfo("'TKIND_UNION' objects are currently not supported!"); + TlbImp.logInfo("'TKIND_UNION' objects are currently not supported!"); } } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/TypeComp.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/TypeComp.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/TypeComp.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/TypeComp.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2012 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/TypeInfo.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/TypeInfo.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/TypeInfo.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/TypeInfo.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2012 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/TypeInfoUtil.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/TypeInfoUtil.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/TypeInfoUtil.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/TypeInfoUtil.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2013 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/TypeLib.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/TypeLib.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/TypeLib.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/TypeLib.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2012 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM; @@ -188,8 +199,7 @@ * @return the hresult */ public HRESULT IsName( - /* [annotation][out][in] */ - LPOLESTR szNameBuf, + /* [annotation][out][in] */ LPOLESTR szNameBuf, /* [in] */ULONG lHashVal, /* [out] */BOOLByReference pfName) { @@ -214,10 +224,9 @@ * @return the hresult */ public HRESULT FindName( - /* [annotation][out][in] */ - BSTRByReference szNameBuf, + /* [annotation][out][in] */ LPOLESTR szNameBuf, /* [in] */ULONG lHashVal, - /* [length_is][size_is][out] */ITypeInfo[] ppTInfo, + /* [length_is][size_is][out] */Pointer[] ppTInfo, /* [length_is][size_is][out] */MEMBERID[] rgMemId, /* [out][in] */USHORTByReference pcFound) { @@ -233,7 +242,7 @@ * the t lib attr */ public void ReleaseTLibAttr(/* [in] */TLIBATTR pTLibAttr) { - this._invokeNativeObject(12, new Object[] { this.getPointer() }, - HRESULT.class); + this._invokeNativeObject(12, new Object[] { this.getPointer(), + pTLibAttr.getPointer() }, HRESULT.class); } } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/TypeLibUtil.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/TypeLibUtil.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/TypeLibUtil.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/TypeLibUtil.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,17 +1,30 @@ /* Copyright (c) 2013 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM; +import com.sun.jna.Native; +import com.sun.jna.Pointer; import com.sun.jna.WString; import com.sun.jna.platform.win32.Guid.CLSID; import com.sun.jna.platform.win32.Kernel32; @@ -20,6 +33,7 @@ import com.sun.jna.platform.win32.OaIdl.TYPEKIND; import com.sun.jna.platform.win32.Ole32; import com.sun.jna.platform.win32.OleAuto; +import com.sun.jna.platform.win32.WTypes; import com.sun.jna.platform.win32.WTypes.BSTRByReference; import com.sun.jna.platform.win32.WTypes.LPOLESTR; import com.sun.jna.platform.win32.WinDef.BOOLByReference; @@ -363,32 +377,29 @@ * @param name * the name * @param hashVal - * the hash val - * @param found - * the found + * the hash val or 0 if unknown + * @param maxResult + * maximum number of items to search * @return the find name */ - public FindName FindName(String name, int hashVal, short found) { - /* [annotation][out][in] */ - BSTRByReference szNameBuf = new BSTRByReference( - OleAuto.INSTANCE.SysAllocString(name)); - /* [in] */ULONG lHashVal = new ULONG(hashVal); - /* [out][in] */USHORTByReference pcFound = new USHORTByReference(found); + public FindName FindName(String name, int hashVal, short maxResult) { + Pointer p = Ole32.INSTANCE.CoTaskMemAlloc((name.length() + 1L) * Native.WCHAR_SIZE); + WTypes.LPOLESTR olestr = new WTypes.LPOLESTR(p); + olestr.setValue(name); - HRESULT hr = this.typelib.FindName(szNameBuf, lHashVal, null, null, - pcFound); - COMUtils.checkRC(hr); + ULONG lHashVal = new ULONG(hashVal); + USHORTByReference pcFound = new USHORTByReference(maxResult); - found = pcFound.getValue().shortValue(); - /* [length_is][size_is][out] */ITypeInfo[] ppTInfo = new ITypeInfo[found]; - /* [length_is][size_is][out] */MEMBERID[] rgMemId = new MEMBERID[found]; - hr = this.typelib.FindName(szNameBuf, lHashVal, ppTInfo, rgMemId, + Pointer[] ppTInfo = new Pointer[maxResult]; + MEMBERID[] rgMemId = new MEMBERID[maxResult]; + HRESULT hr = this.typelib.FindName(olestr, lHashVal, ppTInfo, rgMemId, pcFound); COMUtils.checkRC(hr); - FindName findName = new FindName(szNameBuf.getString(), ppTInfo, - rgMemId, found); - OLEAUTO.SysFreeString(szNameBuf.getValue()); + FindName findName = new FindName(olestr.getValue(), ppTInfo, + rgMemId, pcFound.getValue().shortValue()); + + Ole32.INSTANCE.CoTaskMemFree(p); return findName; } @@ -404,7 +415,7 @@ private String nameBuf; /** The p t info. */ - private ITypeInfo[] pTInfo; + private Pointer[] pTInfo; /** The rg mem id. */ private MEMBERID[] rgMemId; @@ -414,22 +425,22 @@ /** * Instantiates a new find name. - * - * @param nameBuf + * @param nameBuf * the name buf * @param pTInfo * the t info * @param rgMemId - * the rg mem id + * the rg mem id * @param pcFound - * the pc found */ - public FindName(String nameBuf, ITypeInfo[] pTInfo, MEMBERID[] rgMemId, - short pcFound) { + FindName(String nameBuf, Pointer[] pTInfo, MEMBERID[] rgMemId, + short pcFound) { this.nameBuf = nameBuf; - this.pTInfo = pTInfo; - this.rgMemId = rgMemId; + this.pTInfo = new Pointer[pcFound]; + this.rgMemId = new MEMBERID[pcFound]; this.pcFound = pcFound; + System.arraycopy(pTInfo, 0, this.pTInfo, 0, pcFound); + System.arraycopy(rgMemId, 0, this.rgMemId, 0, pcFound); } /** @@ -447,7 +458,12 @@ * @return the t info */ public ITypeInfo[] getTInfo() { - return pTInfo; + ITypeInfo[] values=new ITypeInfo[pcFound]; + for(int i=0;i getFieldOrder() { - return Arrays.asList(new String[] { "vtbl" }); - } - - protected UnknownVTable.ByReference constructVTable() { - return new UnknownVTable.ByReference(); - } - - protected void initVTable(final IUnknownCallback callback) { - this.vtbl.QueryInterfaceCallback = new UnknownVTable.QueryInterfaceCallback() { - @Override - public HRESULT invoke(Pointer thisPointer, REFIID.ByValue refid, PointerByReference ppvObject) { - return callback.QueryInterface(refid, ppvObject); - } - }; - this.vtbl.AddRefCallback = new UnknownVTable.AddRefCallback() { - @Override - public int invoke(Pointer thisPointer) { - return callback.AddRef(); - } - }; - this.vtbl.ReleaseCallback = new UnknownVTable.ReleaseCallback() { - @Override - public int invoke(Pointer thisPointer) { - return callback.Release(); - } - }; - } - -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM; + +import java.util.List; + +import com.sun.jna.Pointer; +import com.sun.jna.Structure; +import com.sun.jna.platform.win32.Guid.REFIID; +import com.sun.jna.platform.win32.WinNT.HRESULT; +import com.sun.jna.ptr.PointerByReference; + +public class UnknownListener extends Structure { + public static final List FIELDS = createFieldsOrder("vtbl"); + public UnknownVTable.ByReference vtbl; + + public UnknownListener(IUnknownCallback callback) { + this.vtbl = this.constructVTable(); + this.initVTable(callback); + super.write(); + } + + @Override + protected List getFieldOrder() { + return FIELDS; + } + + protected UnknownVTable.ByReference constructVTable() { + return new UnknownVTable.ByReference(); + } + + protected void initVTable(final IUnknownCallback callback) { + this.vtbl.QueryInterfaceCallback = new UnknownVTable.QueryInterfaceCallback() { + @Override + public HRESULT invoke(Pointer thisPointer, REFIID refid, PointerByReference ppvObject) { + return callback.QueryInterface(refid, ppvObject); + } + }; + this.vtbl.AddRefCallback = new UnknownVTable.AddRefCallback() { + @Override + public int invoke(Pointer thisPointer) { + return callback.AddRef(); + } + }; + this.vtbl.ReleaseCallback = new UnknownVTable.ReleaseCallback() { + @Override + public int invoke(Pointer thisPointer) { + return callback.Release(); + } + }; + } + +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/UnknownVTable.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/UnknownVTable.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/UnknownVTable.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/UnknownVTable.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,49 +1,60 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM; - -import java.util.Arrays; -import java.util.List; - -import com.sun.jna.Pointer; -import com.sun.jna.Structure; -import com.sun.jna.platform.win32.Guid.REFIID; -import com.sun.jna.platform.win32.WinNT; -import com.sun.jna.ptr.PointerByReference; -import com.sun.jna.win32.StdCallLibrary; - -public class UnknownVTable extends Structure { - public static class ByReference extends UnknownVTable implements Structure.ByReference { - } - - public QueryInterfaceCallback QueryInterfaceCallback; - public AddRefCallback AddRefCallback; - public ReleaseCallback ReleaseCallback; - - @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "QueryInterfaceCallback", "AddRefCallback", "ReleaseCallback" }); - } - - public static interface QueryInterfaceCallback extends StdCallLibrary.StdCallCallback { - WinNT.HRESULT invoke(Pointer thisPointer, REFIID.ByValue refid, PointerByReference ppvObject); - } - - public static interface AddRefCallback extends StdCallLibrary.StdCallCallback { - int invoke(Pointer thisPointer); - } - - public static interface ReleaseCallback extends StdCallLibrary.StdCallCallback { - int invoke(Pointer thisPointer); - } -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM; + +import java.util.List; + +import com.sun.jna.Pointer; +import com.sun.jna.Structure; +import com.sun.jna.platform.win32.Guid.REFIID; +import com.sun.jna.platform.win32.WinNT; +import com.sun.jna.ptr.PointerByReference; +import com.sun.jna.win32.StdCallLibrary; + +public class UnknownVTable extends Structure { + public static class ByReference extends UnknownVTable implements Structure.ByReference { + } + + public static final List FIELDS = createFieldsOrder("QueryInterfaceCallback", "AddRefCallback", "ReleaseCallback"); + public QueryInterfaceCallback QueryInterfaceCallback; + public AddRefCallback AddRefCallback; + public ReleaseCallback ReleaseCallback; + + @Override + protected List getFieldOrder() { + return FIELDS; + } + + public static interface QueryInterfaceCallback extends StdCallLibrary.StdCallCallback { + WinNT.HRESULT invoke(Pointer thisPointer, REFIID refid, PointerByReference ppvObject); + } + + public static interface AddRefCallback extends StdCallLibrary.StdCallCallback { + int invoke(Pointer thisPointer); + } + + public static interface ReleaseCallback extends StdCallLibrary.StdCallCallback { + int invoke(Pointer thisPointer); + } +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/AbstractComEventCallbackListener.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/AbstractComEventCallbackListener.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/AbstractComEventCallbackListener.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/AbstractComEventCallbackListener.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,29 +1,40 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM.util; - -import com.sun.jna.platform.win32.COM.IDispatchCallback; - -public abstract class AbstractComEventCallbackListener implements IComEventCallbackListener { - - public AbstractComEventCallbackListener() { - this.dispatchCallback = null; - } - - IDispatchCallback dispatchCallback; - public void setDispatchCallbackListener(IDispatchCallback dispatchCallback) { - this.dispatchCallback = dispatchCallback; - } - - -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM.util; + +import com.sun.jna.platform.win32.COM.IDispatchCallback; + +public abstract class AbstractComEventCallbackListener implements IComEventCallbackListener { + + public AbstractComEventCallbackListener() { + this.dispatchCallback = null; + } + + IDispatchCallback dispatchCallback; + public void setDispatchCallbackListener(IDispatchCallback dispatchCallback) { + this.dispatchCallback = dispatchCallback; + } + + +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComEventCallback.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComEventCallback.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComEventCallback.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComEventCallback.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,27 +1,38 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM.util.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.METHOD }) -@Inherited -public @interface ComEventCallback { - int dispid() default -1; // default to dispid unknown - String name() default ""; -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM.util.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.METHOD }) +@Inherited +public @interface ComEventCallback { + int dispid() default -1; // default to dispid unknown + String name() default ""; +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComInterface.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComInterface.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComInterface.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComInterface.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,26 +1,37 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM.util.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.TYPE }) -@Inherited -public @interface ComInterface { - String iid() default ""; -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM.util.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.TYPE }) +@Inherited +public @interface ComInterface { + String iid() default ""; +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComMethod.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComMethod.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComMethod.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComMethod.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,27 +1,38 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM.util.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.METHOD }) -@Inherited -public @interface ComMethod { - String name() default ""; - int dispId() default -1; //default to dispid unknown -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM.util.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.METHOD }) +@Inherited +public @interface ComMethod { + String name() default ""; + int dispId() default -1; //default to dispid unknown +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComObject.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComObject.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComObject.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComObject.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,27 +1,38 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM.util.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.TYPE }) -@Inherited -public @interface ComObject { - String clsId() default ""; - String progId() default ""; -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM.util.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.TYPE }) +@Inherited +public @interface ComObject { + String clsId() default ""; + String progId() default ""; +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComProperty.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComProperty.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComProperty.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComProperty.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.COM.util.annotation; @@ -23,4 +34,5 @@ @Inherited public @interface ComProperty { String name() default ""; + int dispId() default -1; //default to dispid unknown } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,273 +1,300 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM.util; - -import java.lang.Thread.UncaughtExceptionHandler; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ThreadFactory; - -import com.sun.jna.Pointer; -import com.sun.jna.WString; -import com.sun.jna.platform.win32.Guid; -import com.sun.jna.platform.win32.WinDef; -import com.sun.jna.platform.win32.Guid.IID; -import com.sun.jna.platform.win32.Guid.REFIID; -import com.sun.jna.platform.win32.OaIdl.DISPID; -import com.sun.jna.platform.win32.OaIdl.DISPIDByReference; -import com.sun.jna.platform.win32.OaIdl.EXCEPINFO; -import com.sun.jna.platform.win32.OleAuto.DISPPARAMS; -import com.sun.jna.platform.win32.Variant; -import com.sun.jna.platform.win32.Variant.VARIANT; -import com.sun.jna.platform.win32.Variant.VariantArg; -import com.sun.jna.platform.win32.WinDef.LCID; -import com.sun.jna.platform.win32.WinDef.UINT; -import com.sun.jna.platform.win32.WinDef.UINTByReference; -import com.sun.jna.platform.win32.WinDef.WORD; -import com.sun.jna.platform.win32.WinError; -import com.sun.jna.platform.win32.WinNT.HRESULT; -import com.sun.jna.platform.win32.COM.COMException; -import com.sun.jna.platform.win32.COM.Dispatch; -import com.sun.jna.platform.win32.COM.DispatchListener; -import com.sun.jna.platform.win32.COM.IDispatch; -import com.sun.jna.platform.win32.COM.IDispatchCallback; -import com.sun.jna.platform.win32.COM.Unknown; -import com.sun.jna.platform.win32.COM.util.annotation.ComEventCallback; -import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; -import com.sun.jna.ptr.IntByReference; -import com.sun.jna.ptr.PointerByReference; - -public class CallbackProxy implements IDispatchCallback { - - public CallbackProxy(Factory factory, Class comEventCallbackInterface, - IComEventCallbackListener comEventCallbackListener) { - this.factory = factory; - this.comEventCallbackInterface = comEventCallbackInterface; - this.comEventCallbackListener = comEventCallbackListener; - this.listenedToRiid = this.createRIID(comEventCallbackInterface); - this.dsipIdMap = this.createDispIdMap(comEventCallbackInterface); - this.dispatchListener = new DispatchListener(this); - this.executorService = Executors.newSingleThreadExecutor(new ThreadFactory() { - @Override - public Thread newThread(Runnable r) { - Thread thread = new Thread(r, "COM Event Callback executor"); - thread.setDaemon(true); - thread.setUncaughtExceptionHandler(new UncaughtExceptionHandler() { - @Override - public void uncaughtException(Thread t, Throwable e) { - CallbackProxy.this.factory.comThread.uncaughtExceptionHandler.uncaughtException(t, e); - } - }); - return thread; - } - }); - } - - Factory factory; - Class comEventCallbackInterface; - IComEventCallbackListener comEventCallbackListener; - REFIID.ByValue listenedToRiid; - public DispatchListener dispatchListener; - Map dsipIdMap; - ExecutorService executorService; - - REFIID.ByValue createRIID(Class comEventCallbackInterface) { - ComInterface comInterfaceAnnotation = comEventCallbackInterface.getAnnotation(ComInterface.class); - if (null == comInterfaceAnnotation) { - throw new COMException( - "advise: Interface must define a value for either iid via the ComInterface annotation"); - } - String iidStr = comInterfaceAnnotation.iid(); - if (null == iidStr || iidStr.isEmpty()) { - throw new COMException("ComInterface must define a value for iid"); - } - return new REFIID.ByValue(new IID(iidStr).getPointer()); - } - - Map createDispIdMap(Class comEventCallbackInterface) { - Map map = new HashMap(); - - for (Method meth : comEventCallbackInterface.getMethods()) { - ComEventCallback annotation = meth.getAnnotation(ComEventCallback.class); - if (null != annotation) { - int dispId = annotation.dispid(); - if (-1 == dispId) { - dispId = this.fetchDispIdFromName(annotation); - } - map.put(new DISPID(dispId), meth); - } - } - - return map; - } - - int fetchDispIdFromName(ComEventCallback annotation) { - // TODO - return -1; - } - - void invokeOnThread(final DISPID dispIdMember, final REFIID.ByValue riid, LCID lcid, WORD wFlags, - final DISPPARAMS.ByReference pDispParams) { - // decode arguments - // must decode them on this thread, and create a proxy for any COM objects (IDispatch) - // this will AddRef on the COM object so that it is not cleaned up before we can use it - // on the thread that does the java callback. - List rjargs = new ArrayList(); - if (pDispParams.cArgs.intValue() > 0) { - VariantArg vargs = pDispParams.rgvarg; - vargs.setArraySize(pDispParams.cArgs.intValue()); - for (Variant.VARIANT varg : vargs.variantArg) { - Object jarg = Convert.toJavaObject(varg); - if (jarg instanceof IDispatch) { - IDispatch dispatch = (IDispatch) jarg; - //get raw IUnknown interface - PointerByReference ppvObject = new PointerByReference(); - IID iid = com.sun.jna.platform.win32.COM.IUnknown.IID_IUNKNOWN; - dispatch.QueryInterface(new REFIID.ByValue(iid), ppvObject); - Unknown rawUnk = new Unknown(ppvObject.getValue()); - long unknownId = Pointer.nativeValue( rawUnk.getPointer() ); - int n = rawUnk.Release(); - //Note: unlike in other places, there is currently no COM ref already added for this pointer - IUnknown unk = CallbackProxy.this.factory.createProxy(IUnknown.class, unknownId, dispatch); - rjargs.add(unk); - } else { - rjargs.add(jarg); - } - } - } - final List jargs = new ArrayList(rjargs); - Runnable invokation = new Runnable() { - @Override - public void run() { - try { - if (CallbackProxy.this.dsipIdMap.containsKey(dispIdMember)) { - Method eventMethod = CallbackProxy.this.dsipIdMap.get(dispIdMember); - if (eventMethod.getParameterTypes().length != jargs.size()) { - CallbackProxy.this.comEventCallbackListener.errorReceivingCallbackEvent( - "Trying to invoke method " + eventMethod + " with " + jargs.size() + " arguments", - null); - } else { - try { - // need to convert arguments maybe - List margs = new ArrayList(); - Class[] params = eventMethod.getParameterTypes(); - for (int i = 0; i < eventMethod.getParameterTypes().length; ++i) { - Class paramType = params[i]; - Object jobj = jargs.get(i); - if (jobj != null && paramType.getAnnotation(ComInterface.class) != null) { - if (jobj instanceof IUnknown) { - IUnknown unk = (IUnknown) jobj; - Object mobj = unk.queryInterface(paramType); - margs.add(mobj); - } else { - throw new RuntimeException("Cannot convert argument " + jobj.getClass() - + " to ComInterface " + paramType); - } - } else { - margs.add(jobj); - } - } - eventMethod.invoke(comEventCallbackListener, margs.toArray()); - } catch (Exception e) { - CallbackProxy.this.comEventCallbackListener.errorReceivingCallbackEvent( - "Exception invoking method " + eventMethod, e); - } - } - } else { - CallbackProxy.this.comEventCallbackListener.errorReceivingCallbackEvent( - "No method found with dispId = " + dispIdMember, null); - } - } catch (Exception e) { - CallbackProxy.this.comEventCallbackListener.errorReceivingCallbackEvent( - "Exception receiving callback event ", e); - } - } - }; - this.executorService.execute(invokation); - } - - @Override - public Pointer getPointer() { - return this.dispatchListener.getPointer(); - } - - // ------------------------ IDispatch ------------------------------ - @Override - public HRESULT GetTypeInfoCount(UINTByReference pctinfo) { - return new HRESULT(WinError.E_NOTIMPL); - } - - @Override - public HRESULT GetTypeInfo(UINT iTInfo, LCID lcid, PointerByReference ppTInfo) { - return new HRESULT(WinError.E_NOTIMPL); - } - - @Override - public HRESULT GetIDsOfNames(REFIID.ByValue riid, WString[] rgszNames, int cNames, LCID lcid, - DISPIDByReference rgDispId) { - return new HRESULT(WinError.E_NOTIMPL); - } - - @Override - public HRESULT Invoke(DISPID dispIdMember, REFIID.ByValue riid, LCID lcid, WORD wFlags, - DISPPARAMS.ByReference pDispParams, VARIANT.ByReference pVarResult, EXCEPINFO.ByReference pExcepInfo, - IntByReference puArgErr) { - - this.invokeOnThread(dispIdMember, riid, lcid, wFlags, pDispParams); - - return WinError.S_OK; - } - - // ------------------------ IUnknown ------------------------------ - @Override - public HRESULT QueryInterface(REFIID.ByValue refid, PointerByReference ppvObject) { - if (null == ppvObject) { - return new HRESULT(WinError.E_POINTER); - } - - if (refid.equals(this.listenedToRiid)) { - ppvObject.setValue(this.getPointer()); - return WinError.S_OK; - } - - if (new Guid.IID(refid.getPointer()).equals(Unknown.IID_IUNKNOWN)) { - ppvObject.setValue(this.getPointer()); - return WinError.S_OK; - } - - if (new Guid.IID(refid.getPointer()).equals(Dispatch.IID_IDISPATCH)) { - ppvObject.setValue(this.getPointer()); - return WinError.S_OK; - } - - return new HRESULT(WinError.E_NOINTERFACE); - } - - public int AddRef() { - return 0; - } - - public int Release() { - return 0; - } - -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM.util; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.sun.jna.Pointer; +import com.sun.jna.WString; +import com.sun.jna.platform.win32.Guid.IID; +import com.sun.jna.platform.win32.Guid.REFIID; +import com.sun.jna.platform.win32.OaIdl.DISPID; +import com.sun.jna.platform.win32.OaIdl.DISPIDByReference; +import com.sun.jna.platform.win32.OaIdl.EXCEPINFO; +import com.sun.jna.platform.win32.OleAuto.DISPPARAMS; +import com.sun.jna.platform.win32.Variant; +import com.sun.jna.platform.win32.Variant.VARIANT; +import com.sun.jna.platform.win32.WinDef.LCID; +import com.sun.jna.platform.win32.WinDef.UINT; +import com.sun.jna.platform.win32.WinDef.UINTByReference; +import com.sun.jna.platform.win32.WinDef.WORD; +import com.sun.jna.platform.win32.WinError; +import com.sun.jna.platform.win32.WinNT.HRESULT; +import com.sun.jna.platform.win32.COM.COMException; +import com.sun.jna.platform.win32.COM.COMUtils; +import com.sun.jna.platform.win32.COM.Dispatch; +import com.sun.jna.platform.win32.COM.DispatchListener; +import com.sun.jna.platform.win32.COM.IDispatchCallback; +import com.sun.jna.platform.win32.COM.Unknown; +import com.sun.jna.platform.win32.COM.util.annotation.ComEventCallback; +import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; +import com.sun.jna.ptr.IntByReference; +import com.sun.jna.ptr.PointerByReference; + +public class CallbackProxy implements IDispatchCallback { + // Helper declarations, initialized to default values by jvm + private static boolean DEFAULT_BOOLEAN; + private static byte DEFAULT_BYTE; + private static short DEFAULT_SHORT; + private static int DEFAULT_INT; + private static long DEFAULT_LONG; + private static float DEFAULT_FLOAT; + private static double DEFAULT_DOUBLE; + + public CallbackProxy(ObjectFactory factory, Class comEventCallbackInterface, + IComEventCallbackListener comEventCallbackListener) { + this.factory = factory; + this.comEventCallbackInterface = comEventCallbackInterface; + this.comEventCallbackListener = comEventCallbackListener; + this.listenedToRiid = this.createRIID(comEventCallbackInterface); + this.dsipIdMap = this.createDispIdMap(comEventCallbackInterface); + this.dispatchListener = new DispatchListener(this); + } + + ObjectFactory factory; + Class comEventCallbackInterface; + IComEventCallbackListener comEventCallbackListener; + REFIID listenedToRiid; + public DispatchListener dispatchListener; + Map dsipIdMap; + + REFIID createRIID(Class comEventCallbackInterface) { + ComInterface comInterfaceAnnotation = comEventCallbackInterface.getAnnotation(ComInterface.class); + if (null == comInterfaceAnnotation) { + throw new COMException( + "advise: Interface must define a value for either iid via the ComInterface annotation"); + } + String iidStr = comInterfaceAnnotation.iid(); + if (null == iidStr || iidStr.isEmpty()) { + throw new COMException("ComInterface must define a value for iid"); + } + return new REFIID(new IID(iidStr).getPointer()); + } + + Map createDispIdMap(Class comEventCallbackInterface) { + Map map = new HashMap(); + + for (Method meth : comEventCallbackInterface.getMethods()) { + ComEventCallback annotation = meth.getAnnotation(ComEventCallback.class); + if (null != annotation) { + int dispId = annotation.dispid(); + if (-1 == dispId) { + dispId = this.fetchDispIdFromName(annotation); + } + if(dispId == -1) { + CallbackProxy.this.comEventCallbackListener.errorReceivingCallbackEvent( + "DISPID for " + meth.getName() + " not found", + null); + } + map.put(new DISPID(dispId), meth); + } + } + + return map; + } + + int fetchDispIdFromName(ComEventCallback annotation) { + // TODO + return -1; + } + + void invokeOnThread(final DISPID dispIdMember, final REFIID riid, LCID lcid, WORD wFlags, + final DISPPARAMS.ByReference pDispParams) { + + VARIANT[] arguments = pDispParams.getArgs(); + + final Method eventMethod = CallbackProxy.this.dsipIdMap.get(dispIdMember); + if (eventMethod == null) { + CallbackProxy.this.comEventCallbackListener.errorReceivingCallbackEvent( + "No method found with dispId = " + dispIdMember, null); + return; + } + + /** + * DISPPARAMs provides two different ways to pass arguments. + * + * Arguments can be passed as a linear list with all arguments + * specified to a certain position (positional) or the position of + * an argument can be passed via the rgdispidNamedArgs array + * (named). + * + * pDispParams.rgvarg (length in pDispParams.cArgs) contains all + * arguments (named + position based) + * + * pDispParams.rgdispidNamedArgs (length in pDispParams.cNamedArgs) + * contains the named parameters as DISPIDs - the DISPIDs are the + * target index in the method signature (zero based). + * + * Each entry in pDispParams.rgvarg is either position based or name + * based and the position bases arguments are passed in reverse + * order, so getting this: + * + * rgvarg = ["arg1", "arg2", "arg3", "arg4", "arg5"] + * rgdispidNamedArgs = [3, 4] + * + * Would lead to this paramater array in the handler: + * + * ["arg5", "arg4", "arg3", "arg1", "arg2"] + * + * See also: + * https://msdn.microsoft.com/de-de/library/windows/desktop/ms221653%28v=vs.85%29.aspx + */ + + // Arguments are converted to the JAVA side and IDispatch Interfaces + // are wrapped into an ProxyObject if so requested. + // + // Out-Parameter need to be specified as VARIANT, VARIANT args are + // not converted, so COM memory allocation rules apply. + + DISPID[] positionMap = pDispParams.getRgdispidNamedArgs(); + + final Class[] paramTypes = eventMethod.getParameterTypes(); + final Object[] params = new Object[paramTypes.length]; + + // Handle position based parameters first + for ( int i = 0; i < params.length && (arguments.length - positionMap.length - i) > 0; i++) { + Class targetClass = paramTypes[i]; + Variant.VARIANT varg = arguments[arguments.length - i - 1]; + params[i] = Convert.toJavaObject(varg, targetClass, factory, true, false); + } + + for ( int i = 0; i < positionMap.length; i++) { + int targetPosition = positionMap[i].intValue(); + if(targetPosition >= params.length) { + // If less parameters are mapped then supplied, ignore + continue; + } + Class targetClass = paramTypes[targetPosition]; + Variant.VARIANT varg = arguments[i]; + params[targetPosition] = Convert.toJavaObject(varg, targetClass, factory, true, false); + } + + + // Make sure the parameters are correctly initialized -- primitives + // are initialized to their default value, else a NullPointer + // exception occurs while doing the call into the target method + for(int i = 0; i < params.length; i++) { + if(params[i] == null && paramTypes[i].isPrimitive()) { + if (paramTypes[i].equals(boolean.class)) { + params[i] = DEFAULT_BOOLEAN; + } else if (paramTypes[i].equals(byte.class)) { + params[i] = DEFAULT_BYTE; + } else if (paramTypes[i].equals(short.class)) { + params[i] = DEFAULT_SHORT; + } else if (paramTypes[i].equals(int.class)) { + params[i] = DEFAULT_INT; + } else if (paramTypes[i].equals(long.class)) { + params[i] = DEFAULT_LONG; + } else if (paramTypes[i].equals(float.class)) { + params[i] = DEFAULT_FLOAT; + } else if (paramTypes[i].equals(double.class)) { + params[i] = DEFAULT_DOUBLE; + } else { + throw new IllegalArgumentException("Class type " + paramTypes[i].getName() + " not mapped to primitive default value."); + } + } + } + + try { + eventMethod.invoke(comEventCallbackListener, params); + } catch (Exception e) { + List decodedClassNames = new ArrayList(params.length); + for(Object o: params) { + if(o == null) { + decodedClassNames.add("NULL"); + } else { + decodedClassNames.add(o.getClass().getName()); + } + } + CallbackProxy.this.comEventCallbackListener.errorReceivingCallbackEvent( + "Exception invoking method " + eventMethod + " supplied: " + decodedClassNames.toString(), e); + } + } + + @Override + public Pointer getPointer() { + return this.dispatchListener.getPointer(); + } + + // ------------------------ IDispatch ------------------------------ + @Override + public HRESULT GetTypeInfoCount(UINTByReference pctinfo) { + return new HRESULT(WinError.E_NOTIMPL); + } + + @Override + public HRESULT GetTypeInfo(UINT iTInfo, LCID lcid, PointerByReference ppTInfo) { + return new HRESULT(WinError.E_NOTIMPL); + } + + @Override + public HRESULT GetIDsOfNames(REFIID riid, WString[] rgszNames, int cNames, LCID lcid, + DISPIDByReference rgDispId) { + return new HRESULT(WinError.E_NOTIMPL); + } + + @Override + public HRESULT Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, + DISPPARAMS.ByReference pDispParams, VARIANT.ByReference pVarResult, EXCEPINFO.ByReference pExcepInfo, + IntByReference puArgErr) { + + assert COMUtils.comIsInitialized() : "Assumption about COM threading broken."; + + this.invokeOnThread(dispIdMember, riid, lcid, wFlags, pDispParams); + + return WinError.S_OK; + } + + // ------------------------ IUnknown ------------------------------ + @Override + public HRESULT QueryInterface(REFIID refid, PointerByReference ppvObject) { + if (null == ppvObject) { + return new HRESULT(WinError.E_POINTER); + } else if (refid.equals(this.listenedToRiid)) { + ppvObject.setValue(this.getPointer()); + return WinError.S_OK; + } else if (refid.getValue().equals(Unknown.IID_IUNKNOWN)) { + ppvObject.setValue(this.getPointer()); + return WinError.S_OK; + } else if (refid.getValue().equals(Dispatch.IID_IDISPATCH)) { + ppvObject.setValue(this.getPointer()); + return WinError.S_OK; + } + + return new HRESULT(WinError.E_NOINTERFACE); + } + + public int AddRef() { + return 0; + } + + public int Release() { + return 0; + } + +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ComEventCallbackCookie.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ComEventCallbackCookie.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ComEventCallbackCookie.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ComEventCallbackCookie.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,28 +1,39 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM.util; - -import com.sun.jna.platform.win32.WinDef.DWORD; - -public class ComEventCallbackCookie implements IComEventCallbackCookie { - - public ComEventCallbackCookie(DWORD value) { - this.value = value; - } - - DWORD value; - public DWORD getValue() { - return this.value; - } - -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM.util; + +import com.sun.jna.platform.win32.WinDef.DWORD; + +public class ComEventCallbackCookie implements IComEventCallbackCookie { + + public ComEventCallbackCookie(DWORD value) { + this.value = value; + } + + DWORD value; + public DWORD getValue() { + return this.value; + } + +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ComThread.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ComThread.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ComThread.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ComThread.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,129 +1,161 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM.util; - -import java.lang.Thread.UncaughtExceptionHandler; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -import com.sun.jna.platform.win32.Ole32; -import com.sun.jna.platform.win32.WinNT; -import com.sun.jna.platform.win32.COM.COMUtils; - -public class ComThread { - - ExecutorService executor; - Runnable firstTask; - boolean requiresInitialisation; - long timeoutMilliseconds; - UncaughtExceptionHandler uncaughtExceptionHandler; - - public ComThread(final String threadName, long timeoutMilliseconds, UncaughtExceptionHandler uncaughtExceptionHandler) { - this(threadName, timeoutMilliseconds, uncaughtExceptionHandler, Ole32.COINIT_MULTITHREADED); - } - - public ComThread(final String threadName, long timeoutMilliseconds, UncaughtExceptionHandler uncaughtExceptionHandler, final int coinitialiseExFlag) { - this.requiresInitialisation = true; - this.timeoutMilliseconds = timeoutMilliseconds; - this.uncaughtExceptionHandler = uncaughtExceptionHandler; - this.firstTask = new Runnable() { - @Override - public void run() { - try { - //If we do not use COINIT_MULTITHREADED, it is necessary to have - // a message loop see - - // [http://www.codeguru.com/cpp/com-tech/activex/apts/article.php/c5529/Understanding-COM-Apartments-Part-I.htm] - // [http://www.codeguru.com/cpp/com-tech/activex/apts/article.php/c5533/Understanding-COM-Apartments-Part-II.htm] - WinNT.HRESULT hr = Ole32.INSTANCE.CoInitializeEx(null, coinitialiseExFlag); - COMUtils.checkRC(hr); - ComThread.this.requiresInitialisation = false; - } catch (Throwable t) { - ComThread.this.uncaughtExceptionHandler.uncaughtException(Thread.currentThread(), t); - } - } - }; - executor = Executors.newSingleThreadExecutor(new ThreadFactory() { - - @Override - public Thread newThread(Runnable r) { - if (!ComThread.this.requiresInitialisation) { - // something has gone wrong! - throw new RuntimeException("ComThread executor has a problem."); - } - Thread thread = new Thread(r, threadName); - //make sure this is a daemon thread, or it will stop JVM existing - // if program does not call terminate(); - thread.setDaemon(true); - - thread.setUncaughtExceptionHandler(new UncaughtExceptionHandler() { - @Override - public void uncaughtException(Thread t, Throwable e) { - ComThread.this.requiresInitialisation = true; - ComThread.this.uncaughtExceptionHandler.uncaughtException(t, e); - } - }); - - return thread; - } - }); - - } - - /** - * Stop the COM Thread. - * - * @param timeoutMilliseconds - * number of milliseconds to wait for a clean shutdown before a - * forced shutdown is attempted - */ - public void terminate(long timeoutMilliseconds) { - try { - - executor.submit(new Runnable() { - @Override - public void run() { - Ole32.INSTANCE.CoUninitialize(); - } - }).get(timeoutMilliseconds, TimeUnit.MILLISECONDS); - - executor.shutdown(); - - } catch (InterruptedException e) { - e.printStackTrace(); - } catch (ExecutionException e) { - e.printStackTrace(); - } catch (TimeoutException e) { - executor.shutdownNow(); - } - } - - @Override - protected void finalize() throws Throwable { - if (!executor.isShutdown()) { - this.terminate(100); - } - } - - public T execute(Callable task) throws TimeoutException, InterruptedException, ExecutionException { - if (this.requiresInitialisation) { - executor.execute(firstTask); - } - return executor.submit(task).get(this.timeoutMilliseconds, TimeUnit.MILLISECONDS); - } - -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM.util; + +import java.lang.Thread.UncaughtExceptionHandler; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import com.sun.jna.platform.win32.Ole32; +import com.sun.jna.platform.win32.WinNT; +import com.sun.jna.platform.win32.COM.COMUtils; + +public class ComThread { + private static ThreadLocal isCOMThread = new ThreadLocal(); + + ExecutorService executor; + Runnable firstTask; + boolean requiresInitialisation; + long timeoutMilliseconds; + UncaughtExceptionHandler uncaughtExceptionHandler; + + public ComThread(final String threadName, long timeoutMilliseconds, UncaughtExceptionHandler uncaughtExceptionHandler) { + this(threadName, timeoutMilliseconds, uncaughtExceptionHandler, Ole32.COINIT_MULTITHREADED); + } + + public ComThread(final String threadName, long timeoutMilliseconds, UncaughtExceptionHandler uncaughtExceptionHandler, final int coinitialiseExFlag) { + this.requiresInitialisation = true; + this.timeoutMilliseconds = timeoutMilliseconds; + this.uncaughtExceptionHandler = uncaughtExceptionHandler; + this.firstTask = new Runnable() { + @Override + public void run() { + try { + //If we do not use COINIT_MULTITHREADED, it is necessary to have + // a message loop see - + // [http://www.codeguru.com/cpp/com-tech/activex/apts/article.php/c5529/Understanding-COM-Apartments-Part-I.htm] + // [http://www.codeguru.com/cpp/com-tech/activex/apts/article.php/c5533/Understanding-COM-Apartments-Part-II.htm] + WinNT.HRESULT hr = Ole32.INSTANCE.CoInitializeEx(null, coinitialiseExFlag); + isCOMThread.set(true); + COMUtils.checkRC(hr); + ComThread.this.requiresInitialisation = false; + } catch (Throwable t) { + ComThread.this.uncaughtExceptionHandler.uncaughtException(Thread.currentThread(), t); + } + } + }; + executor = Executors.newSingleThreadExecutor(new ThreadFactory() { + + @Override + public Thread newThread(Runnable r) { + if (!ComThread.this.requiresInitialisation) { + // something has gone wrong! + throw new RuntimeException("ComThread executor has a problem."); + } + Thread thread = new Thread(r, threadName); + //make sure this is a daemon thread, or it will stop JVM existing + // if program does not call terminate(); + thread.setDaemon(true); + + thread.setUncaughtExceptionHandler(new UncaughtExceptionHandler() { + @Override + public void uncaughtException(Thread t, Throwable e) { + ComThread.this.requiresInitialisation = true; + ComThread.this.uncaughtExceptionHandler.uncaughtException(t, e); + } + }); + + return thread; + } + }); + + } + + /** + * Stop the COM Thread. + * + * @param timeoutMilliseconds + * number of milliseconds to wait for a clean shutdown before a + * forced shutdown is attempted + */ + public void terminate(long timeoutMilliseconds) { + try { + + executor.submit(new Runnable() { + @Override + public void run() { + Ole32.INSTANCE.CoUninitialize(); + } + }).get(timeoutMilliseconds, TimeUnit.MILLISECONDS); + + executor.shutdown(); + + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.printStackTrace(); + } catch (TimeoutException e) { + executor.shutdownNow(); + } + } + + @Override + protected void finalize() throws Throwable { + if (!executor.isShutdown()) { + this.terminate(100); + } + } + + static void setComThread(boolean value) { + isCOMThread.set(value); + } + + public T execute(Callable task) throws TimeoutException, InterruptedException, ExecutionException { + // If the call is done on a COM thread, invoke directly + // if the call comes from outside the invokation is dispatched + // into the Dispatch Thread. + Boolean comThread = isCOMThread.get(); + if(comThread == null) { + comThread = false; + } + if(comThread) { + try { + return task.call(); + } catch (Exception ex) { + throw new ExecutionException(ex); + } + } else { + if (this.requiresInitialisation) { + executor.execute(firstTask); + } + return executor.submit(task).get(this.timeoutMilliseconds, TimeUnit.MILLISECONDS); + } + } + +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Convert.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Convert.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Convert.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Convert.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,92 +1,357 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM.util; - -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.util.Date; - -import com.sun.jna.platform.win32.WTypes; -import com.sun.jna.platform.win32.WinDef; -import com.sun.jna.platform.win32.Variant.VARIANT; - -public class Convert { - - public static VARIANT toVariant(Object value) { - if (value instanceof Boolean) { - return new VARIANT((Boolean) value); - } else if (value instanceof Long) { - return new VARIANT(new WinDef.LONG((Long) value)); - } else if (value instanceof Integer) { - return new VARIANT((Integer) value); - } else if (value instanceof Short) { - return new VARIANT(new WinDef.SHORT((Short) value)); - } else if (value instanceof Float) { - return new VARIANT((Float) value); - } else if (value instanceof Double) { - return new VARIANT((Double) value); - } else if (value instanceof String) { - return new VARIANT((String) value); - } else if (value instanceof Date) { - return new VARIANT((Date) value); - } else if (value instanceof Proxy) { - InvocationHandler ih = Proxy.getInvocationHandler(value); - ProxyObject pobj = (ProxyObject) ih; - return new VARIANT(pobj.getRawDispatch()); - } - if (value instanceof IComEnum) { - IComEnum enm = (IComEnum) value; - return new VARIANT(new WinDef.LONG(enm.getValue())); - } else { - return null; - } - } - - public static Object toJavaObject(VARIANT value) { - if (null==value) return null; - Object vobj = value.getValue(); - if (vobj instanceof WinDef.BOOL) { - return ((WinDef.BOOL) vobj).booleanValue(); - } else if (vobj instanceof WinDef.LONG) { - return ((WinDef.LONG) vobj).longValue(); - } else if (vobj instanceof WinDef.SHORT) { - return ((WinDef.SHORT) vobj).shortValue(); - } else if (vobj instanceof WinDef.UINT) { - return ((WinDef.UINT) vobj).intValue(); - } else if (vobj instanceof WinDef.WORD) { - return ((WinDef.WORD) vobj).intValue(); - } else if (vobj instanceof WTypes.BSTR) { - return ((WTypes.BSTR) vobj).getValue(); - } - return vobj; - } - - public static T toComEnum(Class enumType, Object value) { - try { - Method m = enumType.getMethod("values"); - T[] values = (T[])m.invoke(null); - for(T t: values) { - if (value.equals(t.getValue())) { - return t; - } - } - } catch (NoSuchMethodException e) { - } catch (IllegalAccessException e) { - } catch (IllegalArgumentException e) { - } catch (InvocationTargetException e) { - } - return null; - } -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ +package com.sun.jna.platform.win32.COM.util; + +import com.sun.jna.platform.win32.OaIdl.DATE; +import com.sun.jna.platform.win32.OaIdl.VARIANT_BOOL; +import com.sun.jna.platform.win32.OleAuto; +import com.sun.jna.platform.win32.Variant; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.Date; + +import com.sun.jna.platform.win32.WinDef; +import com.sun.jna.platform.win32.Variant.VARIANT; +import com.sun.jna.platform.win32.WTypes.BSTR; +import com.sun.jna.platform.win32.WinDef.BOOL; +import com.sun.jna.platform.win32.WinDef.BYTE; +import com.sun.jna.platform.win32.WinDef.CHAR; +import com.sun.jna.platform.win32.WinDef.LONG; +import com.sun.jna.platform.win32.WinDef.SHORT; +import com.sun.jna.platform.win32.OaIdl; +import com.sun.jna.platform.win32.OaIdl.SAFEARRAY; +import static com.sun.jna.platform.win32.Variant.VT_ARRAY; +import static com.sun.jna.platform.win32.Variant.VT_BOOL; +import static com.sun.jna.platform.win32.Variant.VT_BSTR; +import static com.sun.jna.platform.win32.Variant.VT_BYREF; +import static com.sun.jna.platform.win32.Variant.VT_CY; +import static com.sun.jna.platform.win32.Variant.VT_DATE; +import static com.sun.jna.platform.win32.Variant.VT_DECIMAL; +import static com.sun.jna.platform.win32.Variant.VT_DISPATCH; +import static com.sun.jna.platform.win32.Variant.VT_EMPTY; +import static com.sun.jna.platform.win32.Variant.VT_ERROR; +import static com.sun.jna.platform.win32.Variant.VT_I1; +import static com.sun.jna.platform.win32.Variant.VT_I2; +import static com.sun.jna.platform.win32.Variant.VT_I4; +import static com.sun.jna.platform.win32.Variant.VT_I8; +import static com.sun.jna.platform.win32.Variant.VT_INT; +import static com.sun.jna.platform.win32.Variant.VT_NULL; +import static com.sun.jna.platform.win32.Variant.VT_R4; +import static com.sun.jna.platform.win32.Variant.VT_R8; +import static com.sun.jna.platform.win32.Variant.VT_RECORD; +import static com.sun.jna.platform.win32.Variant.VT_UI1; +import static com.sun.jna.platform.win32.Variant.VT_UI2; +import static com.sun.jna.platform.win32.Variant.VT_UI4; +import static com.sun.jna.platform.win32.Variant.VT_UI8; +import static com.sun.jna.platform.win32.Variant.VT_UINT; +import static com.sun.jna.platform.win32.Variant.VT_UNKNOWN; +import static com.sun.jna.platform.win32.Variant.VT_VARIANT; +import com.sun.jna.platform.win32.WinDef.PVOID; + +/** + * This class is considered internal to the package. + */ +class Convert { + /** + * Convert a java value into a VARIANT suitable for passing in a COM + * invocation. + * + *

    Implementation notes

    + * + *
      + *
    • VARIANTs are not rewrapped, but passed through unmodified
    • + *
    • A string is wrapped into a BSTR, that is wrapped into the VARIANT. + * The string is allocated as native memory by the VARIANT constructor. + * The BSTR needs to be freed by {@link com.sun.jna.platform.win32.OleAuto#SysFreeString}.
    • + *
    + * + * @param value to be wrapped + * @return wrapped VARIANT + */ + public static VARIANT toVariant(Object value) { + if (value instanceof VARIANT) { + return (VARIANT) value; + } else if (value instanceof BSTR) { + return new VARIANT((BSTR) value); + } else if (value instanceof VARIANT_BOOL) { + return new VARIANT((VARIANT_BOOL) value); + } else if (value instanceof BOOL) { + return new VARIANT((BOOL) value); + } else if (value instanceof LONG) { + return new VARIANT((LONG) value); + } else if (value instanceof SHORT) { + return new VARIANT((SHORT) value); + } else if (value instanceof DATE) { + return new VARIANT((DATE) value); + } else if (value instanceof BYTE) { + return new VARIANT((BYTE) value); + } else if (value instanceof Byte) { + return new VARIANT((Byte) value); + } else if (value instanceof Character) { + return new VARIANT((Character) value); + } else if (value instanceof CHAR) { + return new VARIANT((CHAR) value); + } else if (value instanceof Short) { + return new VARIANT((Short) value); + } else if (value instanceof Integer) { + return new VARIANT((Integer) value); + } else if (value instanceof Long) { + return new VARIANT((Long) value); + } else if (value instanceof Float) { + return new VARIANT((Float) value); + } else if (value instanceof Double) { + return new VARIANT((Double) value); + } else if (value instanceof String) { + return new VARIANT((String) value); + } else if (value instanceof Boolean) { + return new VARIANT((Boolean) value); + } else if (value instanceof com.sun.jna.platform.win32.COM.IDispatch) { + return new VARIANT((com.sun.jna.platform.win32.COM.IDispatch) value); + } else if (value instanceof Date) { + return new VARIANT((Date) value); + } else if (value instanceof Proxy) { + InvocationHandler ih = Proxy.getInvocationHandler(value); + ProxyObject pobj = (ProxyObject) ih; + return new VARIANT(pobj.getRawDispatch()); + } else if (value instanceof IComEnum) { + IComEnum enm = (IComEnum) value; + return new VARIANT(new WinDef.LONG(enm.getValue())); + } else if (value instanceof SAFEARRAY) { + return new VARIANT((SAFEARRAY) value); + } else { + return null; + } + } + + public static Object toJavaObject(VARIANT value, Class targetClass, ObjectFactory factory, boolean addReference, boolean freeValue) { + if (null==value + || value.getVarType().intValue() == VT_EMPTY + || value.getVarType().intValue() == VT_NULL) { + return null; + } + + if (targetClass != null && (!targetClass.isAssignableFrom(Object.class))) { + if (targetClass.isAssignableFrom(value.getClass())) { + return value; + } + + Object vobj = value.getValue(); + if (vobj != null && (targetClass.isAssignableFrom(vobj.getClass()))) { + return vobj; + } + } + + VARIANT inputValue = value; + + if (value.getVarType().intValue() == (VT_BYREF | VT_VARIANT)) { + value = (VARIANT) value.getValue(); + } + + // Passing null or Object.class as targetClass switch to default + // handling + if (targetClass == null || (targetClass.isAssignableFrom(Object.class))) { + + targetClass = null; + + int varType = value.getVarType().intValue(); + + switch (value.getVarType().intValue()) { + case VT_UI1: + case VT_I1: + case VT_BYREF | VT_UI1: + case VT_BYREF | VT_I1: + targetClass = Byte.class; + break; + case VT_I2: + case VT_BYREF | VT_I2: + targetClass = Short.class; + break; + case VT_UI2: + case VT_BYREF | VT_UI2: + targetClass = Character.class; + break; + case VT_INT: + case VT_UINT: + case VT_UI4: + case VT_I4: + case VT_BYREF | VT_I4: + case VT_BYREF | VT_UI4: + case VT_BYREF | VT_INT: + case VT_BYREF | VT_UINT: + targetClass = Integer.class; + break; + case VT_UI8: + case VT_I8: + case VT_BYREF | VT_I8: + case VT_BYREF | VT_UI8: + targetClass = Long.class; + break; + case VT_R4: + case VT_BYREF | VT_R4: + targetClass = Float.class; + break; + case VT_R8: + case VT_BYREF | VT_R8: + targetClass = Double.class; + break; + case VT_BOOL: + case VT_BYREF | VT_BOOL: + targetClass = Boolean.class; + break; + case VT_ERROR: + case VT_BYREF | VT_ERROR: + targetClass = WinDef.SCODE.class; + break; + case VT_CY: + case VT_BYREF | VT_CY: + targetClass = OaIdl.CURRENCY.class; + break; + case VT_DATE: + case VT_BYREF | VT_DATE: + targetClass = Date.class; + break; + case VT_BSTR: + case VT_BYREF | VT_BSTR: + targetClass = String.class; + break; + case VT_UNKNOWN: + case VT_BYREF | VT_UNKNOWN: + targetClass = com.sun.jna.platform.win32.COM.IUnknown.class; + break; + case VT_DISPATCH: + case VT_BYREF | VT_DISPATCH: + targetClass = IDispatch.class; + break; + case VT_BYREF | VT_VARIANT: + targetClass = Variant.class; + break; + case VT_BYREF: + targetClass = PVOID.class; + break; + case VT_BYREF | VT_DECIMAL: + targetClass = OaIdl.DECIMAL.class; + break; + case VT_RECORD: + default: + if ((varType & VT_ARRAY) > 0) { + targetClass = OaIdl.SAFEARRAY.class; + } + } + } + + Object result; + if(Byte.class.equals(targetClass) || byte.class.equals(targetClass)) { + result = value.byteValue(); + } else if (Short.class.equals(targetClass) || short.class.equals(targetClass)) { + result = value.shortValue(); + } else if (Character.class.equals(targetClass) || char.class.equals(targetClass)) { + result = (char) value.intValue(); + } else if (Integer.class.equals(targetClass) || int.class.equals(targetClass)) { + result = value.intValue(); + } else if (Long.class.equals(targetClass) || long.class.equals(targetClass) || IComEnum.class.isAssignableFrom(targetClass)) { + result = value.longValue(); + } else if (Float.class.equals(targetClass) || float.class.equals(targetClass)) { + result = value.floatValue(); + } else if (Double.class.equals(targetClass) || double.class.equals(targetClass)) { + result = value.doubleValue(); + } else if (Boolean.class.equals(targetClass) || boolean.class.equals(targetClass)) { + result = value.booleanValue(); + } else if (Date.class.equals(targetClass)) { + result = value.dateValue(); + } else if (String.class.equals(targetClass)) { + result = value.stringValue(); + } else if (value.getValue() instanceof com.sun.jna.platform.win32.COM.IDispatch) { + com.sun.jna.platform.win32.COM.IDispatch d = (com.sun.jna.platform.win32.COM.IDispatch) value.getValue(); + Object proxy = factory.createProxy(targetClass, d); + // must release a COM reference, createProxy adds one, as does the + // call + if (!addReference) { + int n = d.Release(); + } + result = proxy; + } else { + /* + WinDef.SCODE.class.equals(targetClass) + || OaIdl.CURRENCY.class.equals(targetClass) + || OaIdl.DECIMAL.class.equals(targetClass) + || OaIdl.SAFEARRAY.class.equals(targetClass) + || com.sun.jna.platform.win32.COM.IUnknown.class.equals(targetClass) + || Variant.class.equals(targetClass) + || PVOID.class.equals(targetClass + */ + result = value.getValue(); + } + + if (IComEnum.class.isAssignableFrom(targetClass)) { + result = targetClass.cast(Convert.toComEnum((Class) targetClass, result)); + } + + if(freeValue) { + free(inputValue, result); + } + + return result; + } + + public static T toComEnum(Class enumType, Object value) { + try { + Method m = enumType.getMethod("values"); + T[] values = (T[])m.invoke(null); + for(T t: values) { + if (value.equals(t.getValue())) { + return t; + } + } + } catch (NoSuchMethodException e) { + } catch (IllegalAccessException e) { + } catch (IllegalArgumentException e) { + } catch (InvocationTargetException e) { + } + return null; + } + + /** + * Free the contents of the supplied VARIANT. + * + *

    This method is a companion to {@link #toVariant}. Primary usage is + * to free BSTRs contained in VARIANTs.

    + * + * @param variant to be cleared + * @param javaType type before/after conversion + */ + public static void free(VARIANT variant, Class javaType) { + if((javaType == null || (! BSTR.class.isAssignableFrom(javaType))) + && variant != null + && variant.getVarType().intValue() == Variant.VT_BSTR) { + Object value = variant.getValue(); + if(value instanceof BSTR) { + OleAuto.INSTANCE.SysFreeString((BSTR) value); + } + } + } + + /** + * Free the contents of the supplied VARIANT. + * + *

    This method is a companion to {@link #toVariant}. Primary usage is + * to free BSTRs contained in VARIANTs.

    + * + * @param variant to be cleared + * @param value value before/after conversion + */ + public static void free(VARIANT variant, Object value) { + free(variant, value == null ? null : value.getClass()); + } +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/EnumMoniker.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/EnumMoniker.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/EnumMoniker.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/EnumMoniker.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,166 +1,135 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM.util; - -import java.util.Iterator; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeoutException; - -import com.sun.jna.platform.win32.WinDef; -import com.sun.jna.platform.win32.WinNT; -import com.sun.jna.platform.win32.COM.COMUtils; -import com.sun.jna.platform.win32.COM.Dispatch; -import com.sun.jna.platform.win32.COM.IEnumMoniker; -import com.sun.jna.platform.win32.COM.Moniker; -import com.sun.jna.ptr.PointerByReference; - -/** - * Enumerates the components of a moniker or the monikers in a table of - * monikers. - * - * @see MSDN - * - */ -public class EnumMoniker implements Iterable { - - protected EnumMoniker(IEnumMoniker raw, com.sun.jna.platform.win32.COM.IRunningObjectTable rawRot, - Factory factory) { - this.rawRot = rawRot; - this.raw = raw; - this.factory = factory; - this.comThread = factory.getComThread(); - - try { - WinNT.HRESULT hr = this.comThread.execute(new Callable() { - @Override - public WinNT.HRESULT call() throws Exception { - return EnumMoniker.this.raw.Reset(); - } - }); - COMUtils.checkRC(hr); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } catch (ExecutionException e) { - throw new RuntimeException(e); - } catch (TimeoutException e) { - throw new RuntimeException(e); - } - - this.cacheNext(); - } - - ComThread comThread; - Factory factory; - com.sun.jna.platform.win32.COM.IRunningObjectTable rawRot; - IEnumMoniker raw; - Moniker rawNext; - - protected void cacheNext() { - try { - final PointerByReference rgelt = new PointerByReference(); - final WinDef.ULONGByReference pceltFetched = new WinDef.ULONGByReference(); - - WinNT.HRESULT hr = EnumMoniker.this.comThread.execute(new Callable() { - @Override - public WinNT.HRESULT call() throws Exception { - return EnumMoniker.this.raw.Next(new WinDef.ULONG(1), rgelt, pceltFetched); - } - }); - - if (WinNT.S_OK.equals(hr) && pceltFetched.getValue().intValue() > 0) { - this.rawNext = new Moniker(rgelt.getValue()); - } else { - if (!WinNT.S_FALSE.equals(hr)) { - COMUtils.checkRC(hr); - } - this.rawNext = null; - } - - } catch (InterruptedException e) { - throw new RuntimeException(e); - } catch (ExecutionException e) { - throw new RuntimeException(e); - } catch (TimeoutException e) { - throw new RuntimeException(e); - } - } - - @Override - public Iterator iterator() { - return new Iterator() { - - @Override - public boolean hasNext() { - return null != EnumMoniker.this.rawNext; - } - - @Override - public IDispatch next() { - try { - - final Moniker moniker = EnumMoniker.this.rawNext; - final PointerByReference ppunkObject = new PointerByReference(); - WinNT.HRESULT hr = EnumMoniker.this.comThread.execute(new Callable() { - @Override - public WinNT.HRESULT call() throws Exception { - return EnumMoniker.this.rawRot.GetObject(moniker.getPointer(), ppunkObject); - } - }); - COMUtils.checkRC(hr); - - // To assist debug, can use the following code - // PointerByReference ppbc = new - // PointerByReference(); - // Ole32.INSTANCE.CreateBindCtx(new DWORD(), ppbc); - // - // BSTRByReference ppszDisplayName = new - // BSTRByReference(); - // hr = moniker.GetDisplayName(ppbc.getValue(), - // moniker.getPointer(), ppszDisplayName); - // COMUtils.checkRC(hr); - // String name = ppszDisplayName.getString(); - // Ole32.INSTANCE.CoTaskMemFree(ppszDisplayName.getPointer().getPointer(0)); - - // TODO: Can we assume that the object is an - // IDispatch ? - // Unknown unk = new - // Unknown(ppunkObject.getValue()); - - Dispatch dispatch = new Dispatch(ppunkObject.getValue()); - EnumMoniker.this.cacheNext(); - IDispatch d = EnumMoniker.this.factory.createProxy(IDispatch.class, dispatch); - //must release a COM Ref, GetObject returns a pointer with +1 - int n = dispatch.Release(); - return d; - - } catch (InterruptedException e) { - throw new RuntimeException(e); - } catch (ExecutionException e) { - throw new RuntimeException(e); - } catch (TimeoutException e) { - throw new RuntimeException(e); - } - - } - - @Override - public void remove() { - throw new UnsupportedOperationException("remove"); - } - - }; - } - -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM.util; + +import java.util.Iterator; + +import com.sun.jna.platform.win32.WinDef; +import com.sun.jna.platform.win32.WinNT; +import com.sun.jna.platform.win32.COM.COMUtils; +import com.sun.jna.platform.win32.COM.Dispatch; +import com.sun.jna.platform.win32.COM.IEnumMoniker; +import com.sun.jna.platform.win32.COM.Moniker; +import com.sun.jna.ptr.PointerByReference; + +/** + * Enumerates the components of a moniker or the monikers in a table of + * monikers. + * + * @see MSDN + * + */ +public class EnumMoniker implements Iterable { + + protected EnumMoniker(IEnumMoniker raw, com.sun.jna.platform.win32.COM.IRunningObjectTable rawRot, + ObjectFactory factory) { + + assert COMUtils.comIsInitialized() : "COM not initialized"; + + this.rawRot = rawRot; + this.raw = raw; + this.factory = factory; + + WinNT.HRESULT hr = raw.Reset(); + COMUtils.checkRC(hr); + + this.cacheNext(); + } + + ObjectFactory factory; + com.sun.jna.platform.win32.COM.IRunningObjectTable rawRot; + IEnumMoniker raw; + Moniker rawNext; + + protected void cacheNext() { + assert COMUtils.comIsInitialized() : "COM not initialized"; + final PointerByReference rgelt = new PointerByReference(); + final WinDef.ULONGByReference pceltFetched = new WinDef.ULONGByReference(); + + WinNT.HRESULT hr = this.raw.Next(new WinDef.ULONG(1), rgelt, pceltFetched); + + if (WinNT.S_OK.equals(hr) && pceltFetched.getValue().intValue() > 0) { + this.rawNext = new Moniker(rgelt.getValue()); + } else { + if (!WinNT.S_FALSE.equals(hr)) { + COMUtils.checkRC(hr); + } + this.rawNext = null; + } + } + + @Override + public Iterator iterator() { + return new Iterator() { + + @Override + public boolean hasNext() { + return null != EnumMoniker.this.rawNext; + } + + @Override + public IDispatch next() { + assert COMUtils.comIsInitialized() : "COM not initialized"; + + final Moniker moniker = EnumMoniker.this.rawNext; + final PointerByReference ppunkObject = new PointerByReference(); + WinNT.HRESULT hr = EnumMoniker.this.rawRot.GetObject(moniker.getPointer(), ppunkObject); + COMUtils.checkRC(hr); + + // To assist debug, can use the following code + // PointerByReference ppbc = new + // PointerByReference(); + // Ole32.INSTANCE.CreateBindCtx(new DWORD(), ppbc); + // + // BSTRByReference ppszDisplayName = new + // BSTRByReference(); + // hr = moniker.GetDisplayName(ppbc.getValue(), + // moniker.getPointer(), ppszDisplayName); + // COMUtils.checkRC(hr); + // String name = ppszDisplayName.getString(); + // Ole32.INSTANCE.CoTaskMemFree(ppszDisplayName.getPointer().getPointer(0)); + + // TODO: Can we assume that the object is an + // IDispatch ? + // Unknown unk = new + // Unknown(ppunkObject.getValue()); + + Dispatch dispatch = new Dispatch(ppunkObject.getValue()); + EnumMoniker.this.cacheNext(); + IDispatch d = EnumMoniker.this.factory.createProxy(IDispatch.class, dispatch); + //must release a COM Ref, GetObject returns a pointer with +1 + int n = dispatch.Release(); + return d; + } + + @Override + public void remove() { + throw new UnsupportedOperationException("remove"); + } + + }; + } + +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,278 +1,183 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM.util; - -import java.lang.reflect.Proxy; -import java.util.HashSet; -import java.util.Set; -import java.util.WeakHashMap; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeoutException; - -import com.sun.jna.platform.win32.Guid.CLSID; -import com.sun.jna.platform.win32.Guid.GUID; -import com.sun.jna.platform.win32.Ole32; -import com.sun.jna.platform.win32.OleAuto; -import com.sun.jna.platform.win32.WTypes; -import com.sun.jna.platform.win32.WinDef; -import com.sun.jna.platform.win32.WinNT; -import com.sun.jna.platform.win32.COM.COMException; -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.platform.win32.COM.util.annotation.ComObject; -import com.sun.jna.ptr.PointerByReference; - -public class Factory { - - /** - * Creates a utility COM Factory and a ComThread on which all COM calls are executed. - * NOTE: Remember to call factory.getComThread().terminate() at some appropriate point. - * - */ - public Factory() { - this(new ComThread("Default Factory COM Thread", 5000, new Thread.UncaughtExceptionHandler() { - @Override - public void uncaughtException(Thread t, Throwable e) { - //ignore - } - })); - } - - public Factory(ComThread comThread) { - this.comThread = comThread; - this.registeredObjects = new WeakHashMap(); - } - - @Override - protected void finalize() throws Throwable { - try { - this.disposeAll(); - } finally { - super.finalize(); - } - } - - ComThread comThread; - public ComThread getComThread() { - return this.comThread; - } - - /** - * CoInitialize must be called be fore this method. Either explicitly or - * implicitly via other methods. - * - * @return running object table - */ - public IRunningObjectTable getRunningObjectTable() { - try { - - final PointerByReference rotPtr = new PointerByReference(); - - WinNT.HRESULT hr = this.comThread.execute(new Callable() { - @Override - public WinNT.HRESULT call() throws Exception { - return Ole32.INSTANCE.GetRunningObjectTable(new WinDef.DWORD(0), rotPtr); - } - }); - COMUtils.checkRC(hr); - com.sun.jna.platform.win32.COM.RunningObjectTable raw = new com.sun.jna.platform.win32.COM.RunningObjectTable( - rotPtr.getValue()); - IRunningObjectTable rot = new RunningObjectTable(raw, this); - return rot; - - } catch (InterruptedException e) { - throw new RuntimeException(e); - } catch (ExecutionException e) { - throw new RuntimeException(e); - } catch (TimeoutException e) { - throw new RuntimeException(e); - } - } - - /** - * Creates a ProxyObject for the given interface and IDispatch pointer. - * - */ - public T createProxy(Class comInterface, IDispatch dispatch) { - ProxyObject jop = new ProxyObject(comInterface, dispatch, this); - Object proxy = Proxy.newProxyInstance(comInterface.getClassLoader(), new Class[] { comInterface }, jop); - T result = comInterface.cast(proxy); - return result; - } - - /** only for use when creating ProxyObjects from Callbacks - * - * @param comInterface - * @param unknownId - * @param dispatch - * @return proxy object - */ - T createProxy(Class comInterface, long unknownId, IDispatch dispatch) { - ProxyObject jop = new ProxyObject(comInterface, unknownId, dispatch, this); - Object proxy = Proxy.newProxyInstance(comInterface.getClassLoader(), new Class[] { comInterface }, jop); - T result = comInterface.cast(proxy); - return result; - } - - /** - * Creates a new COM object (CoCreateInstance) for the given progId and - * returns a ProxyObject for the given interface. - */ - public T createObject(Class comInterface) { - try { - - ComObject comObectAnnotation = comInterface.getAnnotation(ComObject.class); - if (null == comObectAnnotation) { - throw new COMException( - "createObject: Interface must define a value for either clsId or progId via the ComInterface annotation"); - } - final GUID guid = this.discoverClsId(comObectAnnotation); - - final PointerByReference ptrDisp = new PointerByReference(); - WinNT.HRESULT hr = this.comThread.execute(new Callable() { - @Override - public WinNT.HRESULT call() throws Exception { - return Ole32.INSTANCE.CoCreateInstance(guid, null, WTypes.CLSCTX_SERVER, IDispatch.IID_IDISPATCH, - ptrDisp); - } - }); - COMUtils.checkRC(hr); - Dispatch d = new Dispatch(ptrDisp.getValue()); - T t = this.createProxy(comInterface,d); - //CoCreateInstance returns a pointer to COM object with a +1 reference count, so we must drop one - //Note: the createProxy adds one - int n = d.Release(); - return t; - - } catch (InterruptedException e) { - throw new RuntimeException(e); - } catch (ExecutionException e) { - throw new RuntimeException(e); - } catch (TimeoutException e) { - throw new RuntimeException(e); - } - } - - /** - * Gets and existing COM object (GetActiveObject) for the given progId and - * returns a ProxyObject for the given interface. - */ - public T fetchObject(Class comInterface) { - try { - ComObject comObectAnnotation = comInterface.getAnnotation(ComObject.class); - if (null == comObectAnnotation) { - throw new COMException( - "createObject: Interface must define a value for either clsId or progId via the ComInterface annotation"); - } - final GUID guid = this.discoverClsId(comObectAnnotation); - - final PointerByReference ptrDisp = new PointerByReference(); - WinNT.HRESULT hr = this.comThread.execute(new Callable() { - @Override - public WinNT.HRESULT call() throws Exception { - return OleAuto.INSTANCE.GetActiveObject(guid, null, ptrDisp); - } - }); - COMUtils.checkRC(hr); - Dispatch d = new Dispatch(ptrDisp.getValue()); - T t = this.createProxy(comInterface, d); - //GetActiveObject returns a pointer to COM object with a +1 reference count, so we must drop one - //Note: the createProxy adds one - d.Release(); - - return t; - } catch (InterruptedException e) { - throw new RuntimeException(e); - } catch (ExecutionException e) { - throw new RuntimeException(e); - } catch (TimeoutException e) { - throw new RuntimeException(e); - } - } - - GUID discoverClsId(ComObject annotation) { - try { - String clsIdStr = annotation.clsId(); - final String progIdStr = annotation.progId(); - if (null != clsIdStr && !clsIdStr.isEmpty()) { - return new CLSID(clsIdStr); - } else if (null != progIdStr && !progIdStr.isEmpty()) { - final CLSID.ByReference rclsid = new CLSID.ByReference(); - - WinNT.HRESULT hr = this.comThread.execute(new Callable() { - @Override - public WinNT.HRESULT call() throws Exception { - return Ole32.INSTANCE.CLSIDFromProgID(progIdStr, rclsid); - } - }); - - COMUtils.checkRC(hr); - return rclsid; - } else { - throw new COMException("ComObject must define a value for either clsId or progId"); - } - } catch (InterruptedException e) { - throw new RuntimeException(e); - } catch (ExecutionException e) { - throw new RuntimeException(e); - } catch (TimeoutException e) { - throw new RuntimeException(e); - } - } - - //factory needs to keep a register of all handles to COM objects so that it can clean them up properly - // (if java had an out of scope clean up destructor like C++, this wouldn't be needed) - WeakHashMap registeredObjects; - public void register(ProxyObject proxyObject) { - synchronized (this.registeredObjects) { - //ProxyObject identity resolves to the underlying native pointer value - // different java ProxyObjects will resolve to the same pointer - // thus we need to count the number of references. - if (this.registeredObjects.containsKey(proxyObject)) { - int r = this.registeredObjects.get(proxyObject); - this.registeredObjects.put(proxyObject, r+1); - } else { - this.registeredObjects.put(proxyObject, 1); - } - } - } - - public void unregister(ProxyObject proxyObject, int d) { - synchronized (this.registeredObjects) { - if (this.registeredObjects.containsKey(proxyObject)) { - int r = this.registeredObjects.get(proxyObject); - if (r > 1) { - this.registeredObjects.put(proxyObject, r-d); - } else { - this.registeredObjects.remove(proxyObject); - } - } else { - throw new RuntimeException("Tried to dispose a ProxyObject that is not registered"); - } - - } - } - - public void disposeAll() { - synchronized (this.registeredObjects) { - Set s = new HashSet(this.registeredObjects.keySet()); - for(ProxyObject proxyObject : s) { - int r = this.registeredObjects.get(proxyObject); - proxyObject.dispose(r); - } - this.registeredObjects.clear(); - } - } -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM.util; + +import com.sun.jna.platform.win32.COM.IDispatch; +import com.sun.jna.platform.win32.COM.IDispatchCallback; +import com.sun.jna.platform.win32.COM.util.annotation.ComObject; +import com.sun.jna.platform.win32.Guid; +import com.sun.jna.platform.win32.OaIdl; +import com.sun.jna.platform.win32.OleAuto; +import com.sun.jna.platform.win32.Variant; +import com.sun.jna.platform.win32.WinDef; +import com.sun.jna.platform.win32.WinNT; +import com.sun.jna.ptr.IntByReference; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; + +/** + * Factory is intended as a simpler to use version of ObjectFactory. + * + *

    The Factory abstracts the necessity to handle COM threading by introducing + * a dispatching thread, that is correctly COM initialized and is used to handle + * all outgoing calls.

    + * + *

    NOTE: Remember to call factory.getComThread().terminate() at some + * appropriate point, when the factory is not used anymore

    + */ +public class Factory extends ObjectFactory { + + private ComThread comThread; + + public Factory() { + this(new ComThread("Default Factory COM Thread", 5000, new Thread.UncaughtExceptionHandler() { + @Override + public void uncaughtException(Thread t, Throwable e) { + //ignore + } + })); + } + + public Factory(ComThread comThread) { + this.comThread = comThread; + } + + private class ProxyObject2 implements InvocationHandler { + + private final Object delegate; + + public ProxyObject2(Object delegate) { + this.delegate = delegate; + } + + @Override + public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable { + if (args != null) { + for (int i = 0; i < args.length; i++) { + if (args[i] != null + && Proxy.isProxyClass(args[i].getClass())) { + InvocationHandler ih = Proxy.getInvocationHandler(args[i]); + if (ih instanceof ProxyObject2) { + args[i] = ((ProxyObject2) ih).delegate; + } + } + } + } + + return comThread.execute(new Callable() { + @Override + public Object call() throws Exception { + return method.invoke(delegate, args); + } + }); + } + } + + private class CallbackProxy2 extends CallbackProxy { + + public CallbackProxy2(ObjectFactory factory, Class comEventCallbackInterface, IComEventCallbackListener comEventCallbackListener) { + super(factory, comEventCallbackInterface, comEventCallbackListener); + } + + @Override + public WinNT.HRESULT Invoke(OaIdl.DISPID dispIdMember, Guid.REFIID riid, WinDef.LCID lcid, WinDef.WORD wFlags, OleAuto.DISPPARAMS.ByReference pDispParams, Variant.VARIANT.ByReference pVarResult, OaIdl.EXCEPINFO.ByReference pExcepInfo, IntByReference puArgErr) { + // Mark callbacks as COM initialized - so normal inline call + // invocation can be used -- see ComThread# + ComThread.setComThread(true); + try { + return super.Invoke(dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + } finally { + ComThread.setComThread(false); + } + } + } + + @Override + public T createProxy(Class comInterface, IDispatch dispatch) { + T result = super.createProxy(comInterface, dispatch); + ProxyObject2 po2 = new ProxyObject2(result); + Object proxy = Proxy.newProxyInstance(comInterface.getClassLoader(), new Class[]{comInterface}, po2); + return (T) proxy; + } + + @Override + Guid.GUID discoverClsId(final ComObject annotation) { + return runInComThread(new Callable() { + public Guid.GUID call() throws Exception { + return Factory.super.discoverClsId(annotation); + } + }); + } + + @Override + public T fetchObject(final Class comInterface) { + // Proxy2 is added by createProxy inside fetch Object + return runInComThread(new Callable() { + public T call() throws Exception { + return Factory.super.fetchObject(comInterface); + } + }); + } + + @Override + public T createObject(final Class comInterface) { + // Proxy2 is added by createProxy inside fetch Object + return runInComThread(new Callable() { + public T call() throws Exception { + return Factory.super.createObject(comInterface); + } + }); + } + + @Override + IDispatchCallback createDispatchCallback(Class comEventCallbackInterface, IComEventCallbackListener comEventCallbackListener) { + return new CallbackProxy2(this, comEventCallbackInterface, comEventCallbackListener); + } + + @Override + public IRunningObjectTable getRunningObjectTable() { + return super.getRunningObjectTable(); + } + + private T runInComThread(Callable callable) { + try { + return comThread.execute(callable); + } catch (TimeoutException ex) { + throw new RuntimeException(ex); + } catch (InterruptedException ex) { + throw new RuntimeException(ex); + } catch (ExecutionException ex) { + throw new RuntimeException(ex); + } + } + + public ComThread getComThread() { + return comThread; + } +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IComEnum.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IComEnum.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IComEnum.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IComEnum.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,17 +1,28 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM.util; - -public interface IComEnum { - long getValue(); -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM.util; + +public interface IComEnum { + long getValue(); +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IComEventCallbackCookie.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IComEventCallbackCookie.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IComEventCallbackCookie.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IComEventCallbackCookie.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,17 +1,28 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM.util; - -public interface IComEventCallbackCookie { - -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM.util; + +public interface IComEventCallbackCookie { + +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IComEventCallbackListener.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IComEventCallbackListener.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IComEventCallbackListener.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IComEventCallbackListener.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,23 +1,34 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM.util; - -import com.sun.jna.platform.win32.COM.IDispatchCallback; - -public interface IComEventCallbackListener { - - void setDispatchCallbackListener(IDispatchCallback dispatchCallback); - - void errorReceivingCallbackEvent(String message, Exception exception); - -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM.util; + +import com.sun.jna.platform.win32.COM.IDispatchCallback; + +public interface IComEventCallbackListener { + + void setDispatchCallbackListener(IDispatchCallback dispatchCallback); + + void errorReceivingCallbackEvent(String message, Exception exception); + +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IConnectionPointContainer.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IConnectionPointContainer.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IConnectionPointContainer.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IConnectionPointContainer.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,21 +1,31 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM.util; - -import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; -import com.sun.jna.platform.win32.COM.util.annotation.ComMethod; - -@ComInterface(iid="{B196B284-BAB4-101A-B69C-00AA00341D07}") -public interface IConnectionPointContainer extends IRawDispatchHandle { - -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM.util; + +import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; + +@ComInterface(iid="{B196B284-BAB4-101A-B69C-00AA00341D07}") +public interface IConnectionPointContainer extends IRawDispatchHandle { + +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IConnectionPoint.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IConnectionPoint.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IConnectionPoint.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IConnectionPoint.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,39 +1,50 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM.util; - -import com.sun.jna.platform.win32.COM.COMException; - -public interface IConnectionPoint { - - /** - * Set up the comEventCallbackListener to receive callback events from the target COM object - * - * @param comEventCallbackInterface - the COM interface that the listener will receive events from - * @param comEventCallbackListener - and object that will receive the callback events - * @return - a cookie that can be used to detach (unadvise) the event callback listener - * - * throws COMException if an error occurs trying to set up the listener on the target COM object, - * see exception cause for details. - * - */ - IComEventCallbackCookie advise(Class comEventCallbackInterface, IComEventCallbackListener comEventCallbackListener) throws COMException; - - /** - * Stop listening for callback events - * - * @param comEventCallbackInterface - the interface that is being listened to - * @param cookie - the cookie that was returned when advise was called - */ - void unadvise(Class comEventCallbackInterface, final IComEventCallbackCookie cookie); -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM.util; + +import com.sun.jna.platform.win32.COM.COMException; + +public interface IConnectionPoint { + + /** + * Set up the comEventCallbackListener to receive callback events from the target COM object + * + * @param comEventCallbackInterface - the COM interface that the listener will receive events from + * @param comEventCallbackListener - and object that will receive the callback events + * @return - a cookie that can be used to detach (unadvise) the event callback listener + * + * throws COMException if an error occurs trying to set up the listener on the target COM object, + * see exception cause for details. + * + */ + IComEventCallbackCookie advise(Class comEventCallbackInterface, IComEventCallbackListener comEventCallbackListener) throws COMException; + + /** + * Stop listening for callback events + * + * @param comEventCallbackInterface - the interface that is being listened to + * @param cookie - the cookie that was returned when advise was called + */ + void unadvise(Class comEventCallbackInterface, final IComEventCallbackCookie cookie); +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IDispatch.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IDispatch.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IDispatch.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IDispatch.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,24 +1,39 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM.util; - -/** - * Java friendly version of {@link com.sun.jna.platform.win32.COM.IDispatch}. - * - */ -public interface IDispatch extends IUnknown { - - void setProperty(String name, T value); - T getProperty(Class returnType, String name, Object... args); - T invokeMethod(Class returnType, String name, Object... args); -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM.util; + +import com.sun.jna.platform.win32.OaIdl.DISPID; + +/** + * Java friendly version of {@link com.sun.jna.platform.win32.COM.IDispatch}. + * + */ +public interface IDispatch extends IUnknown { + void setProperty(String name, T value); + T getProperty(Class returnType, String name, Object... args); + T invokeMethod(Class returnType, String name, Object... args); + void setProperty(DISPID dispid, T value); + T getProperty(Class returnType, DISPID dispid, Object... args); + T invokeMethod(Class returnType, DISPID dispid, Object... args); +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IRawDispatchHandle.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IRawDispatchHandle.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IRawDispatchHandle.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IRawDispatchHandle.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,24 +1,35 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM.util; - -import com.sun.jna.platform.win32.COM.IDispatch; - -/** - * IF you want to access the underlying raw (com.sun.jna.platform.win32.COM.IDispatch) object - * then have your @ComObject or @ComInterface interface extends this interface. - * - */ -public interface IRawDispatchHandle { - IDispatch getRawDispatch(); -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM.util; + +import com.sun.jna.platform.win32.COM.IDispatch; + +/** + * IF you want to access the underlying raw (com.sun.jna.platform.win32.COM.IDispatch) object + * then have your @ComObject or @ComInterface interface extends this interface. + * + */ +public interface IRawDispatchHandle { + IDispatch getRawDispatch(); +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IRunningObjectTable.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IRunningObjectTable.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IRunningObjectTable.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IRunningObjectTable.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,41 +1,52 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM.util; - -import java.util.List; - -/** - * Java friendly version of - * {@link com.sun.jna.platform.win32.COM.IRunningObjectTable} - * - */ -public interface IRunningObjectTable { - - /** - * Creates and returns an enumerator of all the objects currently registered - * in the running object table (ROT). - * - */ - Iterable enumRunning(); - - /** - * Gets all the active (running) objects that support the give interface. - * - * Enumerates the running objects (via enumRunning), and returns a list of - * those for which queryInterface(iid) gives a valid result. - * - * @param comInterface - * @return active objects - */ - List getActiveObjectsByInterface(Class comInterface); -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM.util; + +import java.util.List; + +/** + * Java friendly version of + * {@link com.sun.jna.platform.win32.COM.IRunningObjectTable} + * + */ +public interface IRunningObjectTable { + + /** + * Creates and returns an enumerator of all the objects currently registered + * in the running object table (ROT). + * + */ + Iterable enumRunning(); + + /** + * Gets all the active (running) objects that support the give interface. + * + * Enumerates the running objects (via enumRunning), and returns a list of + * those for which queryInterface(iid) gives a valid result. + * + * @param comInterface + * @return active objects + */ + List getActiveObjectsByInterface(Class comInterface); +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IUnknown.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IUnknown.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IUnknown.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IUnknown.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,35 +1,46 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM.util; - -import com.sun.jna.platform.win32.COM.COMException; -import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; - -/** - * Java friendly version of the IUnknown interface. - * - * - */ -@ComInterface(iid="{00000000-0000-0000-C000-000000000046}") -public interface IUnknown { - /** - * Returns a proxy object for the given interface. Assuming that the - * interface is annotated with a ComInterface annotation that provides a - * valid iid. - * - * Will throw COMException if an error occurs trying to retrieve the requested interface, - * see exception cause for details. - * - */ - T queryInterface(Class comInterface) throws COMException; -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM.util; + +import com.sun.jna.platform.win32.COM.COMException; +import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; + +/** + * Java friendly version of the IUnknown interface. + * + * + */ +@ComInterface(iid="{00000000-0000-0000-C000-000000000046}") +public interface IUnknown { + /** + * Returns a proxy object for the given interface. Assuming that the + * interface is annotated with a ComInterface annotation that provides a + * valid iid. + * + * Will throw COMException if an error occurs trying to retrieve the requested interface, + * see exception cause for details. + * + */ + T queryInterface(Class comInterface) throws COMException; +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ObjectFactory.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ObjectFactory.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ObjectFactory.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ObjectFactory.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,244 @@ +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM.util; + +import java.lang.reflect.Proxy; + +import com.sun.jna.platform.win32.Guid.CLSID; +import com.sun.jna.platform.win32.Guid.GUID; +import com.sun.jna.platform.win32.Ole32; +import com.sun.jna.platform.win32.OleAuto; +import com.sun.jna.platform.win32.WTypes; +import com.sun.jna.platform.win32.WinDef; +import com.sun.jna.platform.win32.WinNT; +import com.sun.jna.platform.win32.COM.COMException; +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.platform.win32.COM.IDispatchCallback; +import com.sun.jna.platform.win32.COM.util.annotation.ComObject; +import com.sun.jna.platform.win32.Kernel32; +import com.sun.jna.platform.win32.WinDef.LCID; +import com.sun.jna.platform.win32.WinNT.HRESULT; +import com.sun.jna.ptr.PointerByReference; +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +/** + * Factory keeps track of COM objects - all objects created with this factory + * can be disposed by calling {@link Factory#disposeAll() }. + */ +public class ObjectFactory { + @Override + protected void finalize() throws Throwable { + try { + this.disposeAll(); + } finally { + super.finalize(); + } + } + + /** + * CoInitialize must be called be fore this method. Either explicitly or + * implicitly via other methods. + * + * @return running object table + */ + public IRunningObjectTable getRunningObjectTable() { + assert COMUtils.comIsInitialized() : "COM not initialized"; + + final PointerByReference rotPtr = new PointerByReference(); + + HRESULT hr = Ole32.INSTANCE.GetRunningObjectTable(new WinDef.DWORD(0), rotPtr); + + COMUtils.checkRC(hr); + com.sun.jna.platform.win32.COM.RunningObjectTable raw = new com.sun.jna.platform.win32.COM.RunningObjectTable( + rotPtr.getValue()); + IRunningObjectTable rot = new RunningObjectTable(raw, this); + return rot; + } + + /** + * Creates a ProxyObject for the given interface and IDispatch pointer. + * + */ + public T createProxy(Class comInterface, IDispatch dispatch) { + assert COMUtils.comIsInitialized() : "COM not initialized"; + + ProxyObject jop = new ProxyObject(comInterface, dispatch, this); + Object proxy = Proxy.newProxyInstance(comInterface.getClassLoader(), new Class[] { comInterface }, jop); + T result = comInterface.cast(proxy); + return result; + } + + /** + * Creates a new COM object (CoCreateInstance) for the given progId and + * returns a ProxyObject for the given interface. + */ + public T createObject(Class comInterface) { + assert COMUtils.comIsInitialized() : "COM not initialized"; + + ComObject comObectAnnotation = comInterface.getAnnotation(ComObject.class); + if (null == comObectAnnotation) { + throw new COMException( + "createObject: Interface must define a value for either clsId or progId via the ComInterface annotation"); + } + final GUID guid = this.discoverClsId(comObectAnnotation); + + final PointerByReference ptrDisp = new PointerByReference(); + WinNT.HRESULT hr = Ole32.INSTANCE.CoCreateInstance(guid, null, + WTypes.CLSCTX_SERVER, IDispatch.IID_IDISPATCH, ptrDisp); + + COMUtils.checkRC(hr); + Dispatch d = new Dispatch(ptrDisp.getValue()); + T t = this.createProxy(comInterface,d); + //CoCreateInstance returns a pointer to COM object with a +1 reference count, so we must drop one + //Note: the createProxy adds one + int n = d.Release(); + return t; + } + + /** + * Gets and existing COM object (GetActiveObject) for the given progId and + * returns a ProxyObject for the given interface. + */ + public T fetchObject(Class comInterface) { + assert COMUtils.comIsInitialized() : "COM not initialized"; + + ComObject comObectAnnotation = comInterface.getAnnotation(ComObject.class); + if (null == comObectAnnotation) { + throw new COMException( + "createObject: Interface must define a value for either clsId or progId via the ComInterface annotation"); + } + final GUID guid = this.discoverClsId(comObectAnnotation); + + final PointerByReference ptrDisp = new PointerByReference(); + WinNT.HRESULT hr = OleAuto.INSTANCE.GetActiveObject(guid, null, ptrDisp); + + COMUtils.checkRC(hr); + Dispatch d = new Dispatch(ptrDisp.getValue()); + T t = this.createProxy(comInterface, d); + //GetActiveObject returns a pointer to COM object with a +1 reference count, so we must drop one + //Note: the createProxy adds one + d.Release(); + + return t; + } + + GUID discoverClsId(ComObject annotation) { + assert COMUtils.comIsInitialized() : "COM not initialized"; + + String clsIdStr = annotation.clsId(); + final String progIdStr = annotation.progId(); + if (null != clsIdStr && !clsIdStr.isEmpty()) { + return new CLSID(clsIdStr); + } else if (null != progIdStr && !progIdStr.isEmpty()) { + final CLSID.ByReference rclsid = new CLSID.ByReference(); + + WinNT.HRESULT hr = Ole32.INSTANCE.CLSIDFromProgID(progIdStr, rclsid); + + COMUtils.checkRC(hr); + return rclsid; + } else { + throw new COMException("ComObject must define a value for either clsId or progId"); + } + } + + IDispatchCallback createDispatchCallback(Class comEventCallbackInterface, IComEventCallbackListener comEventCallbackListener) { + return new CallbackProxy(this, comEventCallbackInterface, comEventCallbackListener); + } + + // Proxy object release their COM interface reference latest in the + // finalize method, which is run when garbadge collection removes the + // object. + // When the factory is finished, the referenced objects loose their + // 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>(); + public void register(ProxyObject proxyObject) { + synchronized (this.registeredObjects) { + this.registeredObjects.add(new WeakReference(proxyObject)); + } + } + + public void unregister(ProxyObject proxyObject) { + synchronized (this.registeredObjects) { + Iterator> iterator = this.registeredObjects.iterator(); + while(iterator.hasNext()) { + WeakReference weakRef = iterator.next(); + ProxyObject po = weakRef.get(); + if(po == null || po == proxyObject) { + iterator.remove(); + } + } + } + } + + public void disposeAll() { + synchronized (this.registeredObjects) { + List> s = new ArrayList>(this.registeredObjects); + for(WeakReference weakRef : s) { + ProxyObject po = weakRef.get(); + if(po != null) { + po.dispose(); + } + } + this.registeredObjects.clear(); + } + } + + /** + * The Constant LOCALE_USER_DEFAULT. + */ + private final static LCID LOCALE_USER_DEFAULT = Kernel32.INSTANCE.GetUserDefaultLCID(); + + private LCID LCID; + + /** + * Retrieve the LCID to be used for COM calls. + * + * @return If {@code setLCID} is not called retrieves the users default + * locale, else the set LCID. + */ + public LCID getLCID() { + if(LCID != null) { + return LCID; + } else { + return LOCALE_USER_DEFAULT; + } + } + + /** + * Set the LCID to use for COM calls. + * + * @param value override LCID. NULL resets to default. + */ + public void setLCID(LCID value) { + LCID = value; + } +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,648 +1,660 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM.util; - -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Proxy; -import java.util.Date; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeoutException; - -import com.sun.jna.Pointer; -import com.sun.jna.WString; -import com.sun.jna.platform.win32.Guid; -import com.sun.jna.platform.win32.Guid.IID; -import com.sun.jna.platform.win32.Guid.REFIID; -import com.sun.jna.platform.win32.Kernel32; -import com.sun.jna.platform.win32.Kernel32Util; -import com.sun.jna.platform.win32.OaIdl; -import com.sun.jna.platform.win32.OaIdl.DISPID; -import com.sun.jna.platform.win32.OaIdl.DISPIDByReference; -import com.sun.jna.platform.win32.OaIdl.EXCEPINFO; -import com.sun.jna.platform.win32.OleAuto; -import com.sun.jna.platform.win32.OleAuto.DISPPARAMS; -import com.sun.jna.platform.win32.Variant; -import com.sun.jna.platform.win32.Variant.VARIANT; -import com.sun.jna.platform.win32.Variant.VariantArg; -import com.sun.jna.platform.win32.WTypes; -import com.sun.jna.platform.win32.WinDef; -import com.sun.jna.platform.win32.WinDef.DWORDByReference; -import com.sun.jna.platform.win32.WinDef.LCID; -import com.sun.jna.platform.win32.WinDef.UINT; -import com.sun.jna.platform.win32.WinNT; -import com.sun.jna.platform.win32.WinNT.HRESULT; -import com.sun.jna.platform.win32.COM.COMException; -import com.sun.jna.platform.win32.COM.COMUtils; -import com.sun.jna.platform.win32.COM.ConnectionPoint; -import com.sun.jna.platform.win32.COM.ConnectionPointContainer; -import com.sun.jna.platform.win32.COM.Dispatch; -import com.sun.jna.platform.win32.COM.IDispatch; -import com.sun.jna.platform.win32.COM.IDispatchCallback; -import com.sun.jna.platform.win32.COM.Unknown; -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.ComProperty; -import com.sun.jna.ptr.IntByReference; -import com.sun.jna.ptr.PointerByReference; - -/** - * This object acts as the invocation handler for interfaces annotated with - * ComInterface. It wraps all (necessary) low level COM calls and executes them - * on a 'ComThread' held by the Factory object. - */ -public class ProxyObject implements InvocationHandler, com.sun.jna.platform.win32.COM.util.IDispatch, - IRawDispatchHandle { - - public ProxyObject(Class theInterface, IDispatch rawDispatch, Factory factory) { - this.unknownId = -1; - this.rawDispatch = rawDispatch; - this.comThread = factory.getComThread(); - this.theInterface = theInterface; - this.factory = factory; - // make sure dispatch object knows we have a reference to it - // (for debug it is usefult to be able to see how many refs are present - int n = this.rawDispatch.AddRef(); - this.getUnknownId(); // pre cache/calculate it - factory.register(this); - } - - /** when proxy is created for arguments on a call back, they are already on the - * com thread, and hence calling 'getUnknownId' will not work as it uses the ComThread - * however, the unknown pointer value is passed in; - * - * @param theInterface - * @param unknownId - * @param rawDispatch - * @param factory - */ - ProxyObject(Class theInterface, long unknownId, IDispatch rawDispatch, Factory factory) { - this.unknownId = unknownId; - this.rawDispatch = rawDispatch; - this.comThread = factory.getComThread(); - this.theInterface = theInterface; - this.factory = factory; - // make sure dispatch object knows we have a reference to it - // (for debug it is usefult to be able to see how many refs are present - int n = this.rawDispatch.AddRef(); - factory.register(this); - } - - // cached value of the IUnknown interface pointer - // Rules of COM state that querying for the IUnknown interface must return - // an identical pointer value - long unknownId; - - long getUnknownId() { - if (-1 == this.unknownId) { - try { - - final PointerByReference ppvObject = new PointerByReference(); - - Thread current = Thread.currentThread(); - String tn = current.getName(); - - HRESULT hr = this.comThread.execute(new Callable() { - @Override - public HRESULT call() throws Exception { - IID iid = com.sun.jna.platform.win32.COM.IUnknown.IID_IUNKNOWN; - return ProxyObject.this.getRawDispatch().QueryInterface(new REFIID.ByValue(iid), ppvObject); - } - }); - - if (WinNT.S_OK.equals(hr)) { - Dispatch dispatch = new Dispatch(ppvObject.getValue()); - this.unknownId = Pointer.nativeValue(dispatch.getPointer()); - // QueryInterface returns a COM object pointer with a +1 - // reference, we must drop one, - // Note: createProxy adds one; - int n = dispatch.Release(); - } else { - String formatMessageFromHR = Kernel32Util.formatMessage(hr); - throw new COMException("getUnknownId: " + formatMessageFromHR); - } - } catch (Exception e) { - throw new COMException("Error occured when trying get Unknown Id ", e); - } - } - return this.unknownId; - } - - @Override - protected void finalize() throws Throwable { - this.dispose(1); - } - - public void dispose(int r) { - if (((Dispatch) this.rawDispatch).getPointer().equals(Pointer.NULL)) { - // do nothing, already disposed - } else { - for (int i = 0; i < r; ++i) { - // catch result to help with debug - int n = this.rawDispatch.Release(); - int n2 = n; - } - this.factory.unregister(this, r); - ((Dispatch) this.rawDispatch).setPointer(Pointer.NULL); - } - } - - Class theInterface; - Factory factory; - ComThread comThread; - com.sun.jna.platform.win32.COM.IDispatch rawDispatch; - - public com.sun.jna.platform.win32.COM.IDispatch getRawDispatch() { - return this.rawDispatch; - } - - // -------------------- Object ------------------------- - - /* - * The QueryInterface rule state that 'a call to QueryInterface with - * IID_IUnknown must always return the same physical pointer value.' - * - * [http://msdn.microsoft.com/en-us/library/ms686590%28VS.85%29.aspx] - * - * therefore we can compare the pointers - */ - public boolean equals(Object arg) { - if (null == arg) { - return false; - } else if (arg instanceof ProxyObject) { - ProxyObject other = (ProxyObject) arg; - return this.getUnknownId() == other.getUnknownId(); - } else if (Proxy.isProxyClass(arg.getClass())) { - InvocationHandler handler = Proxy.getInvocationHandler(arg); - if (handler instanceof ProxyObject) { - try { - ProxyObject other = (ProxyObject) handler; - return this.getUnknownId() == other.getUnknownId(); - } catch (Exception e) { - // if can't do this comparison, return false - // (queryInterface may throw if COM objects become invalid) - return false; - } - } else { - return false; - } - } else { - return false; - } - }; - - @Override - public int hashCode() { - return Long.valueOf(this.getUnknownId()).intValue(); - // this returns the native pointer peer value - // return this.getRawDispatch().hashCode(); - } - - @Override - public String toString() { - return this.theInterface.getName() + "{unk=" + this.hashCode() + "}"; - } - - // --------------------- InvocationHandler ----------------------------- - @Override - public Object invoke(final Object proxy, final java.lang.reflect.Method method, final Object[] args) - throws Throwable { - return this.invokeSynchronised(proxy, method, args); - } - - /* - * may not necessary for this method to be synchronised as all calls to COM - * are on their own , single, thread. However, might be best not to overlap - * calls to COM object with advise, unadvise, queryInterface, etc. - */ - synchronized Object invokeSynchronised(final Object proxy, final java.lang.reflect.Method method, - final Object[] args) throws Throwable { - if (method.equals(Object.class.getMethod("toString"))) { - return this.toString(); - } else if (method.equals(Object.class.getMethod("equals", Object.class))) { - return this.equals(args[0]); - } else if (method.equals(Object.class.getMethod("hashCode"))) { - return this.hashCode(); - } else if (method.equals(IRawDispatchHandle.class.getMethod("getRawDispatch"))) { - return this.getRawDispatch(); - } else if (method.equals(IUnknown.class.getMethod("queryInterface", Class.class))) { - return this.queryInterface((Class) args[0]); - } else if (method.equals(IConnectionPoint.class.getMethod("advise", Class.class, - IComEventCallbackListener.class))) { - return this.advise((Class) args[0], (IComEventCallbackListener) args[1]); - } else if (method.equals(IConnectionPoint.class.getMethod("unadvise", Class.class, - IComEventCallbackCookie.class))) { - this.unadvise((Class) args[0], (IComEventCallbackCookie) args[1]); - return null; - } - - Class returnType = method.getReturnType(); - boolean isVoid = Void.TYPE.equals(returnType); - - ComProperty prop = method.getAnnotation(ComProperty.class); - if (null != prop) { - if (isVoid) { - String propName = this.getMutatorName(method, prop); - this.setProperty(propName, args[0]); - return null; - } else { - String propName = this.getAccessorName(method, prop); - return this.getProperty(returnType, propName, args); - } - } - - ComMethod meth = method.getAnnotation(ComMethod.class); - if (null != meth) { - String methName = this.getMethodName(method, meth); - Object res = this.invokeMethod(returnType, methName, args); - return res; - } - - return null; - } - - // ---------------------- IConnectionPoint ---------------------- - ConnectionPoint fetchRawConnectionPoint(IID iid) throws InterruptedException, ExecutionException, TimeoutException { - // query for ConnectionPointContainer - IConnectionPointContainer cpc = this.queryInterface(IConnectionPointContainer.class); - Dispatch rawCpcDispatch = (Dispatch) cpc.getRawDispatch(); - final ConnectionPointContainer rawCpc = new ConnectionPointContainer(rawCpcDispatch.getPointer()); - - // find connection point for comEventCallback interface - final REFIID adviseRiid = new REFIID(iid.getPointer()); - final PointerByReference ppCp = new PointerByReference(); - HRESULT hr = factory.getComThread().execute(new Callable() { - @Override - public HRESULT call() throws Exception { - return rawCpc.FindConnectionPoint(adviseRiid, ppCp); - } - }); - COMUtils.checkRC(hr); - final ConnectionPoint rawCp = new ConnectionPoint(ppCp.getValue()); - return rawCp; - } - - public IComEventCallbackCookie advise(Class comEventCallbackInterface, - final IComEventCallbackListener comEventCallbackListener) { - try { - ComInterface comInterfaceAnnotation = comEventCallbackInterface.getAnnotation(ComInterface.class); - if (null == comInterfaceAnnotation) { - throw new COMException( - "advise: Interface must define a value for either iid via the ComInterface annotation"); - } - final IID iid = this.getIID(comInterfaceAnnotation); - - final ConnectionPoint rawCp = this.fetchRawConnectionPoint(iid); - - // create the dispatch listener - final IDispatchCallback rawListener = new CallbackProxy(this.factory, comEventCallbackInterface, - comEventCallbackListener); - // store it the comEventCallback argument, so it is not garbage - // collected. - comEventCallbackListener.setDispatchCallbackListener(rawListener); - // set the dispatch listener to listen to events from the connection - // point - final DWORDByReference pdwCookie = new DWORDByReference(); - HRESULT hr = factory.getComThread().execute(new Callable() { - @Override - public HRESULT call() throws Exception { - return rawCp.Advise(rawListener, pdwCookie); - } - }); - int n = rawCp.Release(); // release before check in case check - // throws exception - COMUtils.checkRC(hr); - - // return the cookie so that a call to stop listening can be made - return new ComEventCallbackCookie(pdwCookie.getValue()); - - } catch (Exception e) { - throw new COMException("Error occured in advise when trying to connect the listener " - + comEventCallbackListener, e); - } - } - - public void unadvise(Class comEventCallbackInterface, final IComEventCallbackCookie cookie) { - try { - ComInterface comInterfaceAnnotation = comEventCallbackInterface.getAnnotation(ComInterface.class); - if (null == comInterfaceAnnotation) { - throw new COMException( - "unadvise: Interface must define a value for iid via the ComInterface annotation"); - } - IID iid = this.getIID(comInterfaceAnnotation); - - final ConnectionPoint rawCp = this.fetchRawConnectionPoint(iid); - - HRESULT hr = factory.getComThread().execute(new Callable() { - @Override - public HRESULT call() throws Exception { - return rawCp.Unadvise(((ComEventCallbackCookie) cookie).getValue()); - } - }); - - rawCp.Release(); - COMUtils.checkRC(hr); - - } catch (Exception e) { - throw new COMException("Error occured in unadvise when trying to disconnect the listener from " + this, e); - } - } - - // --------------------- IDispatch ------------------------------ - @Override - public void setProperty(String name, T value) { - VARIANT v = Convert.toVariant(value); - WinNT.HRESULT hr = this.oleMethod(OleAuto.DISPATCH_PROPERTYPUT, null, this.getRawDispatch(), name, v); - COMUtils.checkRC(hr); - } - - @Override - public T getProperty(Class returnType, String name, Object... args) { - VARIANT[] vargs; - if (null == args) { - vargs = new VARIANT[0]; - } else { - vargs = new VARIANT[args.length]; - } - for (int i = 0; i < vargs.length; ++i) { - vargs[i] = Convert.toVariant(args[i]); - } - Variant.VARIANT.ByReference result = new Variant.VARIANT.ByReference(); - WinNT.HRESULT hr = this.oleMethod(OleAuto.DISPATCH_PROPERTYGET, result, this.getRawDispatch(), name, vargs); - COMUtils.checkRC(hr); - Object jobj = Convert.toJavaObject(result); - if (IComEnum.class.isAssignableFrom(returnType)) { - return (T) Convert.toComEnum((Class) returnType, jobj); - } - if (jobj instanceof IDispatch) { - IDispatch d = (IDispatch) jobj; - T t = this.factory.createProxy(returnType, d); - // must release a COM reference, createProxy adds one, as does the - // call - int n = d.Release(); - return t; - } - return (T) jobj; - } - - @Override - public T invokeMethod(Class returnType, String name, Object... args) { - VARIANT[] vargs; - if (null == args) { - vargs = new VARIANT[0]; - } else { - vargs = new VARIANT[args.length]; - } - for (int i = 0; i < vargs.length; ++i) { - vargs[i] = Convert.toVariant(args[i]); - } - Variant.VARIANT.ByReference result = new Variant.VARIANT.ByReference(); - WinNT.HRESULT hr = this.oleMethod(OleAuto.DISPATCH_METHOD, result, this.getRawDispatch(), name, vargs); - COMUtils.checkRC(hr); - - Object jobj = Convert.toJavaObject(result); - if (IComEnum.class.isAssignableFrom(returnType)) { - return (T) Convert.toComEnum((Class) returnType, jobj); - } - if (jobj instanceof IDispatch) { - IDispatch d = (IDispatch) jobj; - T t = this.factory.createProxy(returnType, d); - // must release a COM reference, createProxy adds one, as does the - // call - int n = d.Release(); - return t; - } - return (T) jobj; - } - - @Override - public T queryInterface(Class comInterface) throws COMException { - try { - ComInterface comInterfaceAnnotation = comInterface.getAnnotation(ComInterface.class); - if (null == comInterfaceAnnotation) { - throw new COMException( - "queryInterface: Interface must define a value for iid via the ComInterface annotation"); - } - final IID iid = this.getIID(comInterfaceAnnotation); - final PointerByReference ppvObject = new PointerByReference(); - - HRESULT hr = this.comThread.execute(new Callable() { - @Override - public HRESULT call() throws Exception { - return ProxyObject.this.getRawDispatch().QueryInterface(new REFIID.ByValue(iid), ppvObject); - } - }); - - if (WinNT.S_OK.equals(hr)) { - Dispatch dispatch = new Dispatch(ppvObject.getValue()); - T t = this.factory.createProxy(comInterface, dispatch); - // QueryInterface returns a COM object pointer with a +1 - // reference, we must drop one, - // Note: createProxy adds one; - int n = dispatch.Release(); - return t; - } else { - String formatMessageFromHR = Kernel32Util.formatMessage(hr); - throw new COMException("queryInterface: " + formatMessageFromHR); - } - } catch (Exception e) { - throw new COMException("Error occured when trying to query for interface " + comInterface.getName(), e); - } - } - - IID getIID(ComInterface annotation) { - String iidStr = annotation.iid(); - if (null != iidStr && !iidStr.isEmpty()) { - return new IID(iidStr); - } else { - throw new COMException("ComInterface must define a value for iid"); - } - } - - // --------------------- ProxyObject --------------------- - - private String getAccessorName(java.lang.reflect.Method method, ComProperty prop) { - if (prop.name().isEmpty()) { - String methName = method.getName(); - if (methName.startsWith("get")) { - return methName.replaceFirst("get", ""); - } else { - throw new RuntimeException( - "Property Accessor name must start with 'get', or set the anotation 'name' value"); - } - } else { - return prop.name(); - } - } - - private String getMutatorName(java.lang.reflect.Method method, ComProperty prop) { - if (prop.name().isEmpty()) { - String methName = method.getName(); - if (methName.startsWith("set")) { - return methName.replaceFirst("set", ""); - } else { - throw new RuntimeException( - "Property Mutator name must start with 'set', or set the anotation 'name' value"); - } - } else { - return prop.name(); - } - } - - private String getMethodName(java.lang.reflect.Method method, ComMethod meth) { - if (meth.name().isEmpty()) { - String methName = method.getName(); - return methName; - } else { - return meth.name(); - } - } - - /** The Constant LOCALE_USER_DEFAULT. */ - public final static LCID LOCALE_USER_DEFAULT = Kernel32.INSTANCE.GetUserDefaultLCID(); - - /** The Constant LOCALE_SYSTEM_DEFAULT. */ - public final static LCID LOCALE_SYSTEM_DEFAULT = Kernel32.INSTANCE.GetSystemDefaultLCID(); - - /* - * @see com.sun.jna.platform.win32.COM.COMBindingBaseObject#oleMethod - */ - protected HRESULT oleMethod(int nType, VARIANT.ByReference pvResult, IDispatch pDisp, String name, VARIANT pArg) - throws COMException { - return this.oleMethod(nType, pvResult, pDisp, name, new VARIANT[] { pArg }); - } - - /* - * @see com.sun.jna.platform.win32.COM.COMBindingBaseObject#oleMethod - */ - protected HRESULT oleMethod(int nType, VARIANT.ByReference pvResult, IDispatch pDisp, DISPID dispId, VARIANT pArg) - throws COMException { - return this.oleMethod(nType, pvResult, pDisp, dispId, new VARIANT[] { pArg }); - } - - /* - * @see com.sun.jna.platform.win32.COM.COMBindingBaseObject#oleMethod - */ - protected HRESULT oleMethod(int nType, VARIANT.ByReference pvResult, IDispatch pDisp, String name) - throws COMException { - return this.oleMethod(nType, pvResult, pDisp, name, (VARIANT[]) null); - } - - /* - * @see com.sun.jna.platform.win32.COM.COMBindingBaseObject#oleMethod - */ - protected HRESULT oleMethod(int nType, VARIANT.ByReference pvResult, IDispatch pDisp, DISPID dispId) - throws COMException { - - return this.oleMethod(nType, pvResult, pDisp, dispId, (VARIANT[]) null); - } - - /* - * @see com.sun.jna.platform.win32.COM.COMBindingBaseObject#oleMethod - */ - protected HRESULT oleMethod(int nType, VARIANT.ByReference pvResult, final IDispatch pDisp, String name, - VARIANT[] pArgs) throws COMException { - try { - if (pDisp == null) - throw new COMException("pDisp (IDispatch) parameter is null!"); - - // variable declaration - final WString[] ptName = new WString[] { new WString(name) }; - final DISPIDByReference pdispID = new DISPIDByReference(); - - // Get DISPID for name passed... - HRESULT hr = this.comThread.execute(new Callable() { - @Override - public HRESULT call() throws Exception { - HRESULT hr = pDisp.GetIDsOfNames(new REFIID.ByValue(Guid.IID_NULL), ptName, 1, LOCALE_USER_DEFAULT, - pdispID); - return hr; - } - }); - COMUtils.checkRC(hr); - - return this.oleMethod(nType, pvResult, pDisp, pdispID.getValue(), pArgs); - } catch (InterruptedException e) { - throw new COMException(e); - } catch (ExecutionException e) { - throw new COMException(e); - } catch (TimeoutException e) { - throw new COMException(e); - } - } - - /* - * @see com.sun.jna.platform.win32.COM.COMBindingBaseObject#oleMethod - */ - protected HRESULT oleMethod(final int nType, final VARIANT.ByReference pvResult, final IDispatch pDisp, - final DISPID dispId, VARIANT[] pArgs) throws COMException { - - if (pDisp == null) - throw new COMException("pDisp (IDispatch) parameter is null!"); - - // variable declaration - int _argsLen = 0; - VARIANT[] _args = null; - final DISPPARAMS.ByReference dp = new DISPPARAMS.ByReference(); - final EXCEPINFO.ByReference pExcepInfo = new EXCEPINFO.ByReference(); - final IntByReference puArgErr = new IntByReference(); - - // make parameter reverse ordering as expected by COM runtime - if ((pArgs != null) && (pArgs.length > 0)) { - _argsLen = pArgs.length; - _args = new VARIANT[_argsLen]; - - int revCount = _argsLen; - for (int i = 0; i < _argsLen; i++) { - _args[i] = pArgs[--revCount]; - } - } - - // Handle special-case for property-puts! - if (nType == OleAuto.DISPATCH_PROPERTYPUT) { - dp.cNamedArgs = new UINT(_argsLen); - dp.rgdispidNamedArgs = new DISPIDByReference(OaIdl.DISPID_PROPERTYPUT); - } - - // Build DISPPARAMS - if (_argsLen > 0) { - dp.cArgs = new UINT(_args.length); - // make pointer of variant array - dp.rgvarg = new VariantArg.ByReference(_args); - - // write 'DISPPARAMS' structure to memory - dp.write(); - } - - // Make the call! - try { - - HRESULT hr = this.comThread.execute(new Callable() { - @Override - public HRESULT call() throws Exception { - return pDisp.Invoke(dispId, new REFIID.ByValue(Guid.IID_NULL), LOCALE_SYSTEM_DEFAULT, - new WinDef.WORD(nType), dp, pvResult, pExcepInfo, puArgErr); - } - }); - - COMUtils.checkRC(hr, pExcepInfo, puArgErr); - return hr; - } catch (InterruptedException e) { - throw new COMException(e); - } catch (ExecutionException e) { - throw new COMException(e); - } catch (TimeoutException e) { - throw new COMException(e); - } - } -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM.util; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Proxy; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; + +import com.sun.jna.Pointer; +import com.sun.jna.WString; +import com.sun.jna.platform.win32.Guid; +import com.sun.jna.platform.win32.Guid.IID; +import com.sun.jna.platform.win32.Guid.REFIID; +import com.sun.jna.platform.win32.Kernel32; +import com.sun.jna.platform.win32.Kernel32Util; +import com.sun.jna.platform.win32.OaIdl; +import com.sun.jna.platform.win32.OaIdl.DISPID; +import com.sun.jna.platform.win32.OaIdl.DISPIDByReference; +import com.sun.jna.platform.win32.OaIdl.EXCEPINFO; +import com.sun.jna.platform.win32.OleAuto; +import com.sun.jna.platform.win32.OleAuto.DISPPARAMS; +import com.sun.jna.platform.win32.Variant; +import com.sun.jna.platform.win32.Variant.VARIANT; +import com.sun.jna.platform.win32.WinDef; +import com.sun.jna.platform.win32.WinDef.DWORDByReference; +import com.sun.jna.platform.win32.WinDef.LCID; +import com.sun.jna.platform.win32.WinNT; +import com.sun.jna.platform.win32.WinNT.HRESULT; +import com.sun.jna.platform.win32.COM.COMException; +import com.sun.jna.platform.win32.COM.COMUtils; +import com.sun.jna.platform.win32.COM.ConnectionPoint; +import com.sun.jna.platform.win32.COM.ConnectionPointContainer; +import com.sun.jna.platform.win32.COM.Dispatch; +import com.sun.jna.platform.win32.COM.IDispatch; +import com.sun.jna.platform.win32.COM.IDispatchCallback; +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.ComProperty; +import com.sun.jna.ptr.IntByReference; +import com.sun.jna.ptr.PointerByReference; + +/** + * This object acts as the invocation handler for interfaces annotated with + * ComInterface. It wraps all (necessary) low level COM calls and dispatches + * them through the COM runtime. + * + *

    The caller of the methods is responsible for correct initialization of the + * COM runtime and appropriate thread-handling - depending on the choosen + * handling model.

    + * + * @see MSDN - Processes, Threads, and Apartments + * @see MSDN - Understanding and Using COM Threading Models + */ +public class ProxyObject implements InvocationHandler, com.sun.jna.platform.win32.COM.util.IDispatch, + IRawDispatchHandle, IConnectionPoint { + + // cached value of the IUnknown interface pointer + // Rules of COM state that querying for the IUnknown interface must return + // an identical pointer value + private long unknownId; + private final Class theInterface; + private final ObjectFactory factory; + private final com.sun.jna.platform.win32.COM.IDispatch rawDispatch; + + public ProxyObject(Class theInterface, IDispatch rawDispatch, ObjectFactory factory) { + this.unknownId = -1; + this.rawDispatch = rawDispatch; + this.theInterface = theInterface; + this.factory = factory; + // make sure dispatch object knows we have a reference to it + // (for debug it is usefult to be able to see how many refs are present + int n = this.rawDispatch.AddRef(); + this.getUnknownId(); // pre cache/calculate it + factory.register(this); + } + + private long getUnknownId() { + assert COMUtils.comIsInitialized() : "COM not initialized"; + + if (-1 == this.unknownId) { + try { + final PointerByReference ppvObject = new PointerByReference(); + + Thread current = Thread.currentThread(); + String tn = current.getName(); + + IID iid = com.sun.jna.platform.win32.COM.IUnknown.IID_IUNKNOWN; + HRESULT hr = ProxyObject.this.getRawDispatch().QueryInterface(new REFIID(iid), ppvObject); + + if (WinNT.S_OK.equals(hr)) { + Dispatch dispatch = new Dispatch(ppvObject.getValue()); + this.unknownId = Pointer.nativeValue(dispatch.getPointer()); + // QueryInterface returns a COM object pointer with a +1 + // reference, we must drop one, + // Note: createProxy adds one; + int n = dispatch.Release(); + } else { + String formatMessageFromHR = Kernel32Util.formatMessage(hr); + throw new COMException("getUnknownId: " + formatMessageFromHR); + } + } catch (Exception e) { + throw new COMException("Error occured when trying get Unknown Id ", e); + } + } + return this.unknownId; + } + + @Override + protected void finalize() throws Throwable { + this.dispose(); + } + + public synchronized void dispose() { + if (! ((Dispatch) this.rawDispatch).getPointer().equals(Pointer.NULL)) { + this.rawDispatch.Release(); + ((Dispatch) this.rawDispatch).setPointer(Pointer.NULL); + factory.unregister(this); + } + } + + @Override + public com.sun.jna.platform.win32.COM.IDispatch getRawDispatch() { + return this.rawDispatch; + } + + // -------------------- Object ------------------------- + + /* + * The QueryInterface rule state that 'a call to QueryInterface with + * IID_IUnknown must always return the same physical pointer value.' + * + * [http://msdn.microsoft.com/en-us/library/ms686590%28VS.85%29.aspx] + * + * therefore we can compare the pointers + */ + @Override + public boolean equals(Object arg) { + if (null == arg) { + return false; + } else if (arg instanceof ProxyObject) { + ProxyObject other = (ProxyObject) arg; + return this.getUnknownId() == other.getUnknownId(); + } else if (Proxy.isProxyClass(arg.getClass())) { + InvocationHandler handler = Proxy.getInvocationHandler(arg); + if (handler instanceof ProxyObject) { + try { + ProxyObject other = (ProxyObject) handler; + return this.getUnknownId() == other.getUnknownId(); + } catch (Exception e) { + // if can't do this comparison, return false + // (queryInterface may throw if COM objects become invalid) + return false; + } + } else { + return false; + } + } else { + return false; + } + }; + + @Override + public int hashCode() { + long id = this.getUnknownId(); + return (int) ((id >>> 32) & 0xFFFFFFFF) + (int) (id & 0xFFFFFFFF); + } + + @Override + public String toString() { + return this.theInterface.getName() + "{unk=" + this.hashCode() + "}"; + } + + // --------------------- InvocationHandler ----------------------------- + @Override + public Object invoke(final Object proxy, final java.lang.reflect.Method method, final Object[] args) + throws Throwable { + boolean declaredAsInterface = + (method.getAnnotation(ComMethod.class) != null) + ||(method.getAnnotation(ComProperty.class) != null); + + if ((! declaredAsInterface) && (method.getDeclaringClass().equals(Object.class) + || method.getDeclaringClass().equals(IRawDispatchHandle.class) + || method.getDeclaringClass().equals(com.sun.jna.platform.win32.COM.util.IUnknown.class) + || method.getDeclaringClass().equals(com.sun.jna.platform.win32.COM.util.IDispatch.class) + || method.getDeclaringClass().equals(IConnectionPoint.class) + )) { + try { + return method.invoke(this, args); + } catch (InvocationTargetException ex) { + throw ex.getCause(); + } + } + + Class returnType = method.getReturnType(); + boolean isVoid = Void.TYPE.equals(returnType); + + ComProperty prop = method.getAnnotation(ComProperty.class); + if (null != prop) { + int dispId = prop.dispId(); + if (isVoid) { + if(dispId != -1) { + this.setProperty(new DISPID(dispId), args[0]); + return null; + } else { + String propName = this.getMutatorName(method, prop); + this.setProperty(propName, args[0]); + return null; + } + } else { + if(dispId != -1) { + return this.getProperty(returnType, new DISPID(dispId), args); + } else { + String propName = this.getAccessorName(method, prop); + return this.getProperty(returnType, propName, args); + } + } + } + + ComMethod meth = method.getAnnotation(ComMethod.class); + if (null != meth) { + Object[] fullLengthArgs = unfoldWhenVarargs(method, args); + int dispId = meth.dispId(); + if(dispId != -1) { + return this.invokeMethod(returnType, new DISPID(dispId), fullLengthArgs); + } else { + String methName = this.getMethodName(method, meth); + return this.invokeMethod(returnType, methName, fullLengthArgs); + } + } + + return null; + } + + // ---------------------- IConnectionPoint ---------------------- + private ConnectionPoint fetchRawConnectionPoint(IID iid) throws InterruptedException, ExecutionException, TimeoutException { + assert COMUtils.comIsInitialized() : "COM not initialized"; + + // query for ConnectionPointContainer + IConnectionPointContainer cpc = this.queryInterface(IConnectionPointContainer.class); + Dispatch rawCpcDispatch = (Dispatch) cpc.getRawDispatch(); + final ConnectionPointContainer rawCpc = new ConnectionPointContainer(rawCpcDispatch.getPointer()); + + // find connection point for comEventCallback interface + final REFIID adviseRiid = new REFIID(iid.getPointer()); + final PointerByReference ppCp = new PointerByReference(); + HRESULT hr = rawCpc.FindConnectionPoint(adviseRiid, ppCp); + COMUtils.checkRC(hr); + final ConnectionPoint rawCp = new ConnectionPoint(ppCp.getValue()); + return rawCp; + } + + public IComEventCallbackCookie advise(Class comEventCallbackInterface, + final IComEventCallbackListener comEventCallbackListener) { + assert COMUtils.comIsInitialized() : "COM not initialized"; + + try { + ComInterface comInterfaceAnnotation = comEventCallbackInterface.getAnnotation(ComInterface.class); + if (null == comInterfaceAnnotation) { + throw new COMException( + "advise: Interface must define a value for either iid via the ComInterface annotation"); + } + final IID iid = this.getIID(comInterfaceAnnotation); + + final ConnectionPoint rawCp = this.fetchRawConnectionPoint(iid); + + // create the dispatch listener + final IDispatchCallback rawListener = factory.createDispatchCallback(comEventCallbackInterface, comEventCallbackListener); + // store it the comEventCallback argument, so it is not garbage + // collected. + comEventCallbackListener.setDispatchCallbackListener(rawListener); + // set the dispatch listener to listen to events from the connection + // point + final DWORDByReference pdwCookie = new DWORDByReference(); + HRESULT hr = rawCp.Advise(rawListener, pdwCookie); + int n = rawCp.Release(); // release before check in case check + // throws exception + COMUtils.checkRC(hr); + + // return the cookie so that a call to stop listening can be made + return new ComEventCallbackCookie(pdwCookie.getValue()); + + } catch (Exception e) { + throw new COMException("Error occured in advise when trying to connect the listener " + + comEventCallbackListener, e); + } + } + + public void unadvise(Class comEventCallbackInterface, final IComEventCallbackCookie cookie) { + assert COMUtils.comIsInitialized() : "COM not initialized"; + + try { + ComInterface comInterfaceAnnotation = comEventCallbackInterface.getAnnotation(ComInterface.class); + if (null == comInterfaceAnnotation) { + throw new COMException( + "unadvise: Interface must define a value for iid via the ComInterface annotation"); + } + IID iid = this.getIID(comInterfaceAnnotation); + + final ConnectionPoint rawCp = this.fetchRawConnectionPoint(iid); + + HRESULT hr = rawCp.Unadvise(((ComEventCallbackCookie) cookie).getValue()); + + rawCp.Release(); + COMUtils.checkRC(hr); + + } catch (Exception e) { + throw new COMException("Error occured in unadvise when trying to disconnect the listener from " + this, e); + } + } + + // --------------------- IDispatch ------------------------------ + @Override + public void setProperty(String name, T value) { + DISPID dispID = resolveDispId(this.getRawDispatch(), name); + setProperty(dispID, value); + } + + @Override + public void setProperty(DISPID dispId, T value) { + assert COMUtils.comIsInitialized() : "COM not initialized"; + + VARIANT v = Convert.toVariant(value); + WinNT.HRESULT hr = this.oleMethod(OleAuto.DISPATCH_PROPERTYPUT, null, this.getRawDispatch(), dispId, v); + Convert.free(v, value); // Free value allocated by Convert#toVariant + COMUtils.checkRC(hr); + } + + @Override + public T getProperty(Class returnType, String name, Object... args) { + DISPID dispID = resolveDispId(this.getRawDispatch(), name); + return getProperty(returnType, dispID, args); + } + + @Override + public T getProperty(Class returnType, DISPID dispID, Object... args) { + VARIANT[] vargs; + if (null == args) { + vargs = new VARIANT[0]; + } else { + vargs = new VARIANT[args.length]; + } + for (int i = 0; i < vargs.length; ++i) { + vargs[i] = Convert.toVariant(args[i]); + } + Variant.VARIANT.ByReference result = new Variant.VARIANT.ByReference(); + WinNT.HRESULT hr = this.oleMethod(OleAuto.DISPATCH_PROPERTYGET, result, this.getRawDispatch(), dispID, vargs); + + for (int i = 0; i < vargs.length; i++) { + // Free value allocated by Convert#toVariant + Convert.free(vargs[i], args[i]); + } + + COMUtils.checkRC(hr); + + return (T) Convert.toJavaObject(result, returnType, factory, false, true); + } + + @Override + public T invokeMethod(Class returnType, String name, Object... args) { + DISPID dispID = resolveDispId(this.getRawDispatch(), name); + return invokeMethod(returnType, dispID, args); + } + + @Override + public T invokeMethod(Class returnType, DISPID dispID, Object... args) { + assert COMUtils.comIsInitialized() : "COM not initialized"; + + VARIANT[] vargs; + if (null == args) { + vargs = new VARIANT[0]; + } else { + vargs = new VARIANT[args.length]; + } + for (int i = 0; i < vargs.length; ++i) { + vargs[i] = Convert.toVariant(args[i]); + } + Variant.VARIANT.ByReference result = new Variant.VARIANT.ByReference(); + WinNT.HRESULT hr = this.oleMethod(OleAuto.DISPATCH_METHOD, result, this.getRawDispatch(), dispID, vargs); + + for (int i = 0; i < vargs.length; i++) { + // Free value allocated by Convert#toVariant + Convert.free(vargs[i], args[i]); + } + + COMUtils.checkRC(hr); + + return (T) Convert.toJavaObject(result, returnType, factory, false, true); + } + + private Object[] unfoldWhenVarargs(java.lang.reflect.Method method, Object[] argParams) { + if (null == argParams) { + return null; + } + if (argParams.length == 0 || !method.isVarArgs() || !(argParams[argParams.length - 1] instanceof Object[])) { + return argParams; + } + // when last parameter is Object[] -> unfold the ellipsis: + Object[] varargs = (Object[]) argParams[argParams.length - 1]; + Object[] args = new Object[argParams.length - 1 + varargs.length]; + System.arraycopy(argParams, 0, args, 0, argParams.length - 1); + System.arraycopy(varargs, 0, args, argParams.length - 1, varargs.length); + return args; + } + + @Override + public T queryInterface(Class comInterface) throws COMException { + assert COMUtils.comIsInitialized() : "COM not initialized"; + + try { + ComInterface comInterfaceAnnotation = comInterface.getAnnotation(ComInterface.class); + if (null == comInterfaceAnnotation) { + throw new COMException( + "queryInterface: Interface must define a value for iid via the ComInterface annotation"); + } + final IID iid = this.getIID(comInterfaceAnnotation); + final PointerByReference ppvObject = new PointerByReference(); + + HRESULT hr = ProxyObject.this.getRawDispatch().QueryInterface(new REFIID(iid), ppvObject); + + if (WinNT.S_OK.equals(hr)) { + Dispatch dispatch = new Dispatch(ppvObject.getValue()); + T t = this.factory.createProxy(comInterface, dispatch); + // QueryInterface returns a COM object pointer with a +1 + // reference, we must drop one, + // Note: createProxy adds one; + int n = dispatch.Release(); + return t; + } else { + String formatMessageFromHR = Kernel32Util.formatMessage(hr); + throw new COMException("queryInterface: " + formatMessageFromHR); + } + } catch (Exception e) { + throw new COMException("Error occured when trying to query for interface " + comInterface.getName(), e); + } + } + + private IID getIID(ComInterface annotation) { + String iidStr = annotation.iid(); + if (null != iidStr && !iidStr.isEmpty()) { + return new IID(iidStr); + } else { + throw new COMException("ComInterface must define a value for iid"); + } + } + + // --------------------- ProxyObject --------------------- + + private String getAccessorName(java.lang.reflect.Method method, ComProperty prop) { + if (prop.name().isEmpty()) { + String methName = method.getName(); + if (methName.startsWith("get")) { + return methName.replaceFirst("get", ""); + } else { + throw new RuntimeException( + "Property Accessor name must start with 'get', or set the anotation 'name' value"); + } + } else { + return prop.name(); + } + } + + private String getMutatorName(java.lang.reflect.Method method, ComProperty prop) { + if (prop.name().isEmpty()) { + String methName = method.getName(); + if (methName.startsWith("set")) { + return methName.replaceFirst("set", ""); + } else { + throw new RuntimeException( + "Property Mutator name must start with 'set', or set the anotation 'name' value"); + } + } else { + return prop.name(); + } + } + + private String getMethodName(java.lang.reflect.Method method, ComMethod meth) { + if (meth.name().isEmpty()) { + String methName = method.getName(); + return methName; + } else { + return meth.name(); + } + } + + /* + * @see com.sun.jna.platform.win32.COM.COMBindingBaseObject#oleMethod + */ + protected HRESULT oleMethod(int nType, VARIANT.ByReference pvResult, IDispatch pDisp, String name, VARIANT pArg) + throws COMException { + return this.oleMethod(nType, pvResult, pDisp, name, new VARIANT[] { pArg }); + } + + /* + * @see com.sun.jna.platform.win32.COM.COMBindingBaseObject#oleMethod + */ + protected HRESULT oleMethod(int nType, VARIANT.ByReference pvResult, IDispatch pDisp, DISPID dispId, VARIANT pArg) + throws COMException { + return this.oleMethod(nType, pvResult, pDisp, dispId, new VARIANT[] { pArg }); + } + + /* + * @see com.sun.jna.platform.win32.COM.COMBindingBaseObject#oleMethod + */ + protected HRESULT oleMethod(int nType, VARIANT.ByReference pvResult, IDispatch pDisp, String name) + throws COMException { + return this.oleMethod(nType, pvResult, pDisp, name, (VARIANT[]) null); + } + + /* + * @see com.sun.jna.platform.win32.COM.COMBindingBaseObject#oleMethod + */ + protected HRESULT oleMethod(int nType, VARIANT.ByReference pvResult, IDispatch pDisp, DISPID dispId) + throws COMException { + + return this.oleMethod(nType, pvResult, pDisp, dispId, (VARIANT[]) null); + } + + protected DISPID resolveDispId(final IDispatch pDisp, String name) { + assert COMUtils.comIsInitialized() : "COM not initialized"; + + if (pDisp == null) + throw new COMException("pDisp (IDispatch) parameter is null!"); + + // variable declaration + final WString[] ptName = new WString[] { new WString(name) }; + final DISPIDByReference pdispID = new DISPIDByReference(); + + // Get DISPID for name passed... + HRESULT hr = pDisp.GetIDsOfNames( + new REFIID(Guid.IID_NULL), + ptName, + 1, + factory.getLCID(), + pdispID); + + COMUtils.checkRC(hr); + + return pdispID.getValue(); + } + + /* + * @see com.sun.jna.platform.win32.COM.COMBindingBaseObject#oleMethod + */ + protected HRESULT oleMethod(int nType, VARIANT.ByReference pvResult, final IDispatch pDisp, String name, + VARIANT[] pArgs) throws COMException { + + return this.oleMethod(nType, pvResult, pDisp, resolveDispId(pDisp, name), pArgs); + } + + /* + * @see com.sun.jna.platform.win32.COM.COMBindingBaseObject#oleMethod + */ + protected HRESULT oleMethod(final int nType, final VARIANT.ByReference pvResult, final IDispatch pDisp, + final DISPID dispId, VARIANT[] pArgs) throws COMException { + + assert COMUtils.comIsInitialized() : "COM not initialized"; + + if (pDisp == null) + throw new COMException("pDisp (IDispatch) parameter is null!"); + + // variable declaration + int _argsLen = 0; + VARIANT[] _args = null; + final DISPPARAMS.ByReference dp = new DISPPARAMS.ByReference(); + final EXCEPINFO.ByReference pExcepInfo = new EXCEPINFO.ByReference(); + final IntByReference puArgErr = new IntByReference(); + + // make parameter reverse ordering as expected by COM runtime + if ((pArgs != null) && (pArgs.length > 0)) { + _argsLen = pArgs.length; + _args = new VARIANT[_argsLen]; + + int revCount = _argsLen; + for (int i = 0; i < _argsLen; i++) { + _args[i] = pArgs[--revCount]; + } + } + + // Handle special-case for property-puts! + if (nType == OleAuto.DISPATCH_PROPERTYPUT) { + dp.setRgdispidNamedArgs(new DISPID[] {OaIdl.DISPID_PROPERTYPUT}); + } + + // Apply "fix" according to + // https://www.delphitools.info/2013/04/30/gaining-visual-basic-ole-super-powers/ + // https://msdn.microsoft.com/en-us/library/windows/desktop/ms221486(v=vs.85).aspx + // + // Summary: there are methods in the word typelibrary that require both + // PROPERTYGET _and_ METHOD to be set. With only one of these set the call + // fails. + // + // The article from delphitools argues, that automation compatible libraries + // need to be compatible with VisualBasic which does not distingish methods + // and property getters and will set both flags always. + // + // The MSDN article advises this behaviour: "[...] Some languages cannot + // distinguish between retrieving a property and calling a method. In this + //case, you should set the flags DISPATCH_PROPERTYGET and DISPATCH_METHOD. + // [...]")) + // + // This was found when trying to bind InchesToPoints from the _Application + // dispatch interface of the MS Word 15 type library + // + // The signature according the ITypeLib Viewer (OLE/COM Object Viewer): + // [id(0x00000172), helpcontext(0x09700172)] + // single InchesToPoints([in] single Inches); + final int finalNType; + if(nType == OleAuto.DISPATCH_METHOD || nType == OleAuto.DISPATCH_PROPERTYGET) { + finalNType = OleAuto.DISPATCH_METHOD | OleAuto.DISPATCH_PROPERTYGET; + } else { + finalNType = nType; + } + + // Build DISPPARAMS + if (_argsLen > 0) { + dp.setArgs(_args); + + // write 'DISPPARAMS' structure to memory + dp.write(); + } + + + HRESULT hr = pDisp.Invoke( + dispId, + new REFIID(Guid.IID_NULL), + factory.getLCID(), + new WinDef.WORD(finalNType), + dp, + pvResult, + pExcepInfo, + puArgErr); + + + COMUtils.checkRC(hr, pExcepInfo, puArgErr); + return hr; + } +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/RunningObjectTable.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/RunningObjectTable.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/COM/util/RunningObjectTable.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/COM/util/RunningObjectTable.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,83 +1,77 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM.util; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeoutException; - -import com.sun.jna.platform.win32.WinNT; -import com.sun.jna.platform.win32.COM.COMException; -import com.sun.jna.platform.win32.COM.COMUtils; -import com.sun.jna.ptr.PointerByReference; - -public class RunningObjectTable implements IRunningObjectTable { - - protected RunningObjectTable(com.sun.jna.platform.win32.COM.RunningObjectTable raw, Factory factory) { - this.raw = raw; - this.factory = factory; - this.comThread = factory.getComThread(); - } - - Factory factory; - ComThread comThread; - com.sun.jna.platform.win32.COM.RunningObjectTable raw; - - @Override - public Iterable enumRunning() { - - try { - - final PointerByReference ppenumMoniker = new PointerByReference(); - - WinNT.HRESULT hr = this.comThread.execute(new Callable() { - @Override - public WinNT.HRESULT call() throws Exception { - return RunningObjectTable.this.raw.EnumRunning(ppenumMoniker); - } - }); - COMUtils.checkRC(hr); - com.sun.jna.platform.win32.COM.EnumMoniker raw = new com.sun.jna.platform.win32.COM.EnumMoniker( - ppenumMoniker.getValue()); - - return new EnumMoniker(raw, this.raw, this.factory); - - } catch (InterruptedException e) { - throw new RuntimeException(e); - } catch (ExecutionException e) { - throw new RuntimeException(e); - } catch (TimeoutException e) { - throw new RuntimeException(e); - } - - } - - @Override - public List getActiveObjectsByInterface(Class comInterface) { - List result = new ArrayList(); - - for (IDispatch obj : this.enumRunning()) { - try { - T dobj = obj.queryInterface(comInterface); - - result.add(dobj); - } catch (COMException ex) { - - } - } - - return result; - } -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), 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.COM.util; + +import java.util.ArrayList; +import java.util.List; + +import com.sun.jna.platform.win32.WinNT; +import com.sun.jna.platform.win32.COM.COMException; +import com.sun.jna.platform.win32.COM.COMUtils; +import com.sun.jna.ptr.PointerByReference; + +public class RunningObjectTable implements IRunningObjectTable { + + protected RunningObjectTable(com.sun.jna.platform.win32.COM.RunningObjectTable raw, ObjectFactory factory) { + this.raw = raw; + this.factory = factory; + } + + ObjectFactory factory; + com.sun.jna.platform.win32.COM.RunningObjectTable raw; + + @Override + public Iterable enumRunning() { + assert COMUtils.comIsInitialized() : "COM not initialized"; + + final PointerByReference ppenumMoniker = new PointerByReference(); + + WinNT.HRESULT hr = this.raw.EnumRunning(ppenumMoniker); + + COMUtils.checkRC(hr); + com.sun.jna.platform.win32.COM.EnumMoniker raw = new com.sun.jna.platform.win32.COM.EnumMoniker( + ppenumMoniker.getValue()); + + return new EnumMoniker(raw, this.raw, this.factory); + } + + @Override + public List getActiveObjectsByInterface(Class comInterface) { + assert COMUtils.comIsInitialized() : "COM not initialized"; + + List result = new ArrayList(); + + for (IDispatch obj : this.enumRunning()) { + try { + T dobj = obj.queryInterface(comInterface); + + result.add(dobj); + } catch (COMException ex) { + + } + } + + return result; + } +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Crypt32.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Crypt32.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Crypt32.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Crypt32.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; @@ -25,88 +36,110 @@ * @author dblock[at]dblock.org */ public interface Crypt32 extends StdCallLibrary { - - Crypt32 INSTANCE = (Crypt32) Native.loadLibrary("Crypt32", - Crypt32.class, W32APIOptions.UNICODE_OPTIONS); - + + Crypt32 INSTANCE = Native.loadLibrary("Crypt32", Crypt32.class, W32APIOptions.DEFAULT_OPTIONS); + /** * The CryptProtectData function performs encryption on the data in a DATA_BLOB - * structure. Typically, only a user with the same logon credential as the encrypter + * structure. Typically, only a user with the same logon credential as the encrypter * can decrypt the data. In addition, the encryption and decryption usually must be * done on the same computer. * @param pDataIn - * Pointer to a DATA_BLOB structure that contains the plaintext to be encrypted. + * Pointer to a DATA_BLOB structure that contains the plaintext to be encrypted. * @param szDataDescr - * String with a readable description of the data to be encrypted. This description - * string is included with the encrypted data. This parameter is optional and can + * String with a readable description of the data to be encrypted. This description + * string is included with the encrypted data. This parameter is optional and can * be set to NULL, except on Windows 2000. * @param pOptionalEntropy - * Pointer to a DATA_BLOB structure that contains a password or other additional - * entropy used to encrypt the data. The DATA_BLOB structure used in the encryption + * Pointer to a DATA_BLOB structure that contains a password or other additional + * entropy used to encrypt the data. The DATA_BLOB structure used in the encryption * phase must also be used in the decryption phase. This parameter can be set to NULL * for no additional entropy. * @param pvReserved - * Reserved for future use and must be set to NULL. + * Reserved for future use and must be set to NULL. * @param pPromptStruct - * Pointer to a CRYPTPROTECT_PROMPTSTRUCT structure that provides information about - * where and when prompts are to be displayed and what the content of those prompts + * Pointer to a CRYPTPROTECT_PROMPTSTRUCT structure that provides information about + * where and when prompts are to be displayed and what the content of those prompts * should be. This parameter can be set to NULL in both the encryption and decryption * phases. * @param dwFlags - * One of CRYPTPROTECT_LOCAL_MACHINE, CRYPTPROTECT_UI_FORBIDDEN, CRYPTPROTECT_AUDIT, + * One of CRYPTPROTECT_LOCAL_MACHINE, CRYPTPROTECT_UI_FORBIDDEN, CRYPTPROTECT_AUDIT, * CRYPTPROTECT_VERIFY_PROTECTION. * @param pDataOut - * Pointer to a DATA_BLOB structure that receives the encrypted data. When you have - * finished using the DATA_BLOB structure, free its pbData member by calling the - * LocalFree function. + * Pointer to a DATA_BLOB structure that receives the encrypted data. When you have + * finished using the DATA_BLOB structure, free its pbData member by calling the + * LocalFree function. * @return - * If the function succeeds, the function returns TRUE. If the function fails, + * If the function succeeds, the function returns TRUE. If the function fails, * it returns FALSE. For extended error information, call GetLastError. */ public boolean CryptProtectData(DATA_BLOB pDataIn, String szDataDescr, - DATA_BLOB pOptionalEntropy, Pointer pvReserved, + DATA_BLOB pOptionalEntropy, Pointer pvReserved, CRYPTPROTECT_PROMPTSTRUCT pPromptStruct, int dwFlags, DATA_BLOB pDataOut); - + /** * The CryptUnprotectData function decrypts and does an integrity check of the data in * a DATA_BLOB structure. Usually, only a user with the same logon credentials as the * encrypter can decrypt the data. In addition, the encryption and decryption must be - * done on the same computer. + * done on the same computer. * @param pDataIn - * Pointer to a DATA_BLOB structure that holds the encrypted data. The DATA_BLOB - * structure's cbData member holds the length of the pbData member's byte string that - * contains the text to be encrypted. + * Pointer to a DATA_BLOB structure that holds the encrypted data. The DATA_BLOB + * structure's cbData member holds the length of the pbData member's byte string that + * contains the text to be encrypted. * @param szDataDescr - * Pointer to a string-readable description of the encrypted data included with the - * encrypted data. This parameter can be set to NULL. When you have finished using - * ppszDataDescr, free it by calling the LocalFree function. + * Pointer to a string-readable description of the encrypted data included with the + * encrypted data. This parameter can be set to NULL. When you have finished using + * ppszDataDescr, free it by calling the LocalFree function. * @param pOptionalEntropy - * Pointer to a DATA_BLOB structure that contains a password or other additional - * entropy used when the data was encrypted. This parameter can be set to NULL; - * however, if an optional entropy DATA_BLOB structure was used in the encryption + * Pointer to a DATA_BLOB structure that contains a password or other additional + * entropy used when the data was encrypted. This parameter can be set to NULL; + * however, if an optional entropy DATA_BLOB structure was used in the encryption * phase, that same DATA_BLOB structure must be used for the decryption phase. * @param pvReserved - * Reserved for future use; must be set to NULL. + * Reserved for future use; must be set to NULL. * @param pPromptStruct - * Pointer to a CRYPTPROTECT_PROMPTSTRUCT structure that provides information about - * where and when prompts are to be displayed and what the content of those prompts - * should be. This parameter can be set to NULL. + * Pointer to a CRYPTPROTECT_PROMPTSTRUCT structure that provides information about + * where and when prompts are to be displayed and what the content of those prompts + * should be. This parameter can be set to NULL. * @param dwFlags - * DWORD value that specifies options for this function. This parameter can be zero, - * in which case no option is set, or CRYPTPROTECT_UI_FORBIDDEN. + * DWORD value that specifies options for this function. This parameter can be zero, + * in which case no option is set, or CRYPTPROTECT_UI_FORBIDDEN. * @param pDataOut - * Pointer to a DATA_BLOB structure where the function stores the decrypted data. + * Pointer to a DATA_BLOB structure where the function stores the decrypted data. * When you have finished using the DATA_BLOB structure, free its pbData member by - * calling the LocalFree function. + * calling the LocalFree function. * @return - * If the function succeeds, the return value is TRUE. If the function fails, the + * If the function succeeds, the return value is TRUE. If the function fails, the * return value is FALSE. */ public boolean CryptUnprotectData(DATA_BLOB pDataIn, PointerByReference szDataDescr, - DATA_BLOB pOptionalEntropy, Pointer pvReserved, + DATA_BLOB pOptionalEntropy, Pointer pvReserved, CRYPTPROTECT_PROMPTSTRUCT pPromptStruct, int dwFlags, DATA_BLOB pDataOut); + + /** + * The CertAddEncodedCertificateToSystemStore function opens the specified + * system store and adds the encoded certificate to it. + * + * @param szCertStoreName + * A null-terminated string that contains the name of the system + * store for the encoded certificate. + * @param pbCertEncoded + * A pointer to a buffer that contains the encoded certificate to + * add. + * @param cbCertEncoded + * The size, in bytes, of the pbCertEncoded buffer. + * @return If the function succeeds, the return value is TRUE.
    + * If the function fails, the return value is FALSE.
    + * CertAddEncodedCertificateToSystemStore depends on the functions + * listed in the following remarks for error handling.
    + * Refer to those function topics for their respective error + * handling behaviors.
    + * For extended error information, call GetLastError. + * @see MSDN + */ + boolean CertAddEncodedCertificateToSystemStore(String szCertStoreName, Pointer pbCertEncoded, int cbCertEncoded); } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Crypt32Util.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Crypt32Util.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Crypt32Util.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Crypt32Util.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; @@ -22,119 +33,145 @@ */ public abstract class Crypt32Util { - /** - * Protect a blob of data. - * @param data - * Data to protect. - * @return - * Protected data. - */ - public static byte[] cryptProtectData(byte[] data) { - return cryptProtectData(data, 0); - } - - /** - * Protect a blob of data with optional flags. - * @param data - * Data to protect. - * @param flags - * Optional flags, eg. CRYPTPROTECT_LOCAL_MACHINE | CRYPTPROTECT_UI_FORBIDDEN. - * @return - * Protected data. - */ - public static byte[] cryptProtectData(byte[] data, int flags) { - return cryptProtectData(data, null, flags, "", null); - } - - /** - * Protect a blob of data. - * @param data - * Data to protect. - * @param entropy - * Optional entropy. - * @param flags - * Optional flags. - * @param description - * Optional description. - * @param prompt - * Prompt structure. - * @return - * Protected bytes. - */ - public static byte[] cryptProtectData(byte[] data, byte[] entropy, int flags, - String description, CRYPTPROTECT_PROMPTSTRUCT prompt) { - DATA_BLOB pDataIn = new DATA_BLOB(data); - DATA_BLOB pDataProtected = new DATA_BLOB(); - DATA_BLOB pEntropy = (entropy == null) ? null : new DATA_BLOB(entropy); - try { - if (! Crypt32.INSTANCE.CryptProtectData(pDataIn, description, - pEntropy, null, prompt, flags, pDataProtected)) { - throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); - } - return pDataProtected.getData(); - } finally { - if (pDataProtected.pbData != null) { - Kernel32.INSTANCE.LocalFree(pDataProtected.pbData); - } - } - } - - /** - * Unprotect a blob of data. - * @param data - * Data to unprotect. - * @return - * Unprotected blob of data. - */ - public static byte[] cryptUnprotectData(byte[] data) { - return cryptUnprotectData(data, 0); - } - - /** - * Unprotect a blob of data. - * @param data - * Data to unprotect. - * @param flags - * Optional flags, eg. CRYPTPROTECT_UI_FORBIDDEN. - * @return - * Unprotected blob of data. - */ - public static byte[] cryptUnprotectData(byte[] data, int flags) { - return cryptUnprotectData(data, null, flags, null); - } - - /** - * Unprotect a blob of data. - * @param data - * Data to unprotect. - * @param entropy - * Optional entropy. - * @param flags - * Optional flags. - * @param prompt - * Optional prompt structure. - * @return - * Unprotected blob of data. - */ - public static byte[] cryptUnprotectData(byte[] data, byte[] entropy, int flags, - CRYPTPROTECT_PROMPTSTRUCT prompt) { - DATA_BLOB pDataIn = new DATA_BLOB(data); - DATA_BLOB pDataUnprotected = new DATA_BLOB(); - DATA_BLOB pEntropy = (entropy == null) ? null : new DATA_BLOB(entropy); - PointerByReference pDescription = new PointerByReference(); - try { - if (! Crypt32.INSTANCE.CryptUnprotectData(pDataIn, pDescription, - pEntropy, null, prompt, flags, pDataUnprotected)) { - throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); - } - return pDataUnprotected.getData(); - } finally { - if (pDataUnprotected.pbData != null) { - Kernel32.INSTANCE.LocalFree(pDataUnprotected.pbData); - } - if (pDescription.getValue() != null) { - Kernel32.INSTANCE.LocalFree(pDescription.getValue()); - } - } - } + /** + * Protect a blob of data. + * @param data + * Data to protect. + * @return + * Protected data. + */ + public static byte[] cryptProtectData(byte[] data) { + return cryptProtectData(data, 0); + } + + /** + * Protect a blob of data with optional flags. + * @param data + * Data to protect. + * @param flags + * Optional flags, eg. CRYPTPROTECT_LOCAL_MACHINE | CRYPTPROTECT_UI_FORBIDDEN. + * @return + * Protected data. + */ + public static byte[] cryptProtectData(byte[] data, int flags) { + return cryptProtectData(data, null, flags, "", null); + } + + /** + * Protect a blob of data. + * @param data + * Data to protect. + * @param entropy + * Optional entropy. + * @param flags + * Optional flags. + * @param description + * Optional description. + * @param prompt + * Prompt structure. + * @return + * Protected bytes. + */ + public static byte[] cryptProtectData(byte[] data, byte[] entropy, int flags, + String description, CRYPTPROTECT_PROMPTSTRUCT prompt) { + DATA_BLOB pDataIn = new DATA_BLOB(data); + DATA_BLOB pDataProtected = new DATA_BLOB(); + DATA_BLOB pEntropy = (entropy == null) ? null : new DATA_BLOB(entropy); + try { + if (! Crypt32.INSTANCE.CryptProtectData(pDataIn, description, + pEntropy, null, prompt, flags, pDataProtected)) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + return pDataProtected.getData(); + } finally { + if (pDataProtected.pbData != null) { + Kernel32Util.freeLocalMemory(pDataProtected.pbData); + } + } + } + + /** + * Unprotect a blob of data. + * @param data + * Data to unprotect. + * @return + * Unprotected blob of data. + */ + public static byte[] cryptUnprotectData(byte[] data) { + return cryptUnprotectData(data, 0); + } + + /** + * Unprotect a blob of data. + * @param data + * Data to unprotect. + * @param flags + * Optional flags, eg. CRYPTPROTECT_UI_FORBIDDEN. + * @return + * Unprotected blob of data. + */ + public static byte[] cryptUnprotectData(byte[] data, int flags) { + return cryptUnprotectData(data, null, flags, null); + } + + /** + * Unprotect a blob of data. + * @param data + * Data to unprotect. + * @param entropy + * Optional entropy. + * @param flags + * Optional flags. + * @param prompt + * Optional prompt structure. + * @return + * Unprotected blob of data. + */ + public static byte[] cryptUnprotectData(byte[] data, byte[] entropy, int flags, + CRYPTPROTECT_PROMPTSTRUCT prompt) { + DATA_BLOB pDataIn = new DATA_BLOB(data); + DATA_BLOB pDataUnprotected = new DATA_BLOB(); + DATA_BLOB pEntropy = (entropy == null) ? null : new DATA_BLOB(entropy); + PointerByReference pDescription = new PointerByReference(); + Win32Exception err = null; + byte[] unProtectedData = null; + try { + if (! Crypt32.INSTANCE.CryptUnprotectData(pDataIn, pDescription, + pEntropy, null, prompt, flags, pDataUnprotected)) { + err = new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } else { + unProtectedData = pDataUnprotected.getData(); + } + } finally { + if (pDataUnprotected.pbData != null) { + try { + Kernel32Util.freeLocalMemory(pDataUnprotected.pbData); + } catch(Win32Exception e) { + if (err == null) { + err = e; + } else { + err.addSuppressed(e); + } + } + } + + if (pDescription.getValue() != null) { + try { + Kernel32Util.freeLocalMemory(pDescription.getValue()); + } catch(Win32Exception e) { + if (err == null) { + err = e; + } else { + err.addSuppressed(e); + } + } + } + } + + if (err != null) { + throw err; + } + + return unProtectedData; + } } \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/DBT.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/DBT.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/DBT.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/DBT.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,18 +1,28 @@ /* Copyright (c) 2012 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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 java.util.Arrays; import java.util.List; import com.sun.jna.Native; @@ -22,15 +32,13 @@ import com.sun.jna.platform.win32.WinDef.LONG; import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.platform.win32.WinUser.HDEVNOTIFY; -import com.sun.jna.win32.StdCallLibrary; /** * Based on dbt.h (various types) - * + * * @author Tobias Wolf, wolf.tobias@gmx.net */ -@SuppressWarnings("serial") -public interface DBT extends StdCallLibrary { +public interface DBT { /** The dbt no disk space. */ int DBT_NO_DISK_SPACE = 0x0047; @@ -66,29 +74,26 @@ int DBT_CUSTOMEVENT = 0x8006; /** The guid devinterface usb device. */ - public GUID GUID_DEVINTERFACE_USB_DEVICE = new GUID( + GUID GUID_DEVINTERFACE_USB_DEVICE = new GUID( "{A5DCBF10-6530-11D2-901F-00C04FB951ED}"); /** The guid devinterface hid. */ - public GUID GUID_DEVINTERFACE_HID = new GUID( - "{4D1E55B2-F16F-11CF-88CB-001111000030}"); + GUID GUID_DEVINTERFACE_HID = new GUID("{4D1E55B2-F16F-11CF-88CB-001111000030}"); /** The guid devinterface volume. */ - public GUID GUID_DEVINTERFACE_VOLUME = new GUID( - "{53F5630D-B6BF-11D0-94F2-00A0C91EFB8B}"); + GUID GUID_DEVINTERFACE_VOLUME = new GUID("{53F5630D-B6BF-11D0-94F2-00A0C91EFB8B}"); /** The guid devinterface keyboard. */ - public GUID GUID_DEVINTERFACE_KEYBOARD = new GUID( - "{884b96c3-56ef-11d1-bc8c-00a0c91405dd}"); + GUID GUID_DEVINTERFACE_KEYBOARD = new GUID("{884b96c3-56ef-11d1-bc8c-00a0c91405dd}"); /** The guid devinterface mouse. */ - public GUID GUID_DEVINTERFACE_MOUSE = new GUID( - "{378DE44C-56EF-11D1-BC8C-00A0C91405DD}"); + GUID GUID_DEVINTERFACE_MOUSE = new GUID("{378DE44C-56EF-11D1-BC8C-00A0C91405DD}"); /** * The Class DEV_BROADCAST_HDR. */ public class DEV_BROADCAST_HDR extends Structure { + public static final List FIELDS = createFieldsOrder("dbch_size", "dbch_devicetype", "dbch_reserved"); /** The dbch_size. */ public int dbch_size = size(); @@ -103,11 +108,12 @@ * Instantiates a new dev broadcast hdr. */ public DEV_BROADCAST_HDR() { + super(); } /** * Instantiates a new dev broadcast hdr. - * + * * @param pointer * the pointer */ @@ -117,7 +123,7 @@ /** * Instantiates a new dev broadcast hdr. - * + * * @param memory * the memory */ @@ -126,14 +132,9 @@ read(); } - /* - * (non-Javadoc) - * - * @see com.sun.jna.Structure#getFieldOrder() - */ - protected List getFieldOrder() { - return Arrays.asList(new String[] { "dbch_size", "dbch_devicetype", - "dbch_reserved" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } @@ -162,6 +163,8 @@ * The Class DEV_BROADCAST_OEM. */ public class DEV_BROADCAST_OEM extends Structure { + public static final List FIELDS = createFieldsOrder("dbco_size", "dbco_devicetype", + "dbco_reserved", "dbco_identifier", "dbco_suppfunc"); /** The dbco_size. */ public int dbco_size = size(); @@ -182,12 +185,12 @@ * Instantiates a new dev broadcast oem. */ public DEV_BROADCAST_OEM() { - // TODO Auto-generated constructor stub + super(); } /** * Instantiates a new dev broadcast oem. - * + * * @param memory * the memory */ @@ -196,14 +199,9 @@ read(); } - /* - * (non-Javadoc) - * - * @see com.sun.jna.Structure#getFieldOrder() - */ - protected List getFieldOrder() { - return Arrays.asList(new String[] { "dbco_size", "dbco_devicetype", - "dbco_reserved", "dbco_identifier", "dbco_suppfunc" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } @@ -211,7 +209,8 @@ * The Class DEV_BROADCAST_DEVNODE. */ public class DEV_BROADCAST_DEVNODE extends Structure { - + public static final List FIELDS = createFieldsOrder("dbcd_size", "dbcd_devicetype", + "dbcd_reserved", "dbcd_devnode"); /** The dbcd_size. */ public int dbcd_size = size(); @@ -228,12 +227,12 @@ * Instantiates a new dev broadcast devnode. */ public DEV_BROADCAST_DEVNODE() { - // TODO Auto-generated constructor stub + super(); } /** * Instantiates a new dev broadcast devnode. - * + * * @param memory * the memory */ @@ -242,14 +241,9 @@ read(); } - /* - * (non-Javadoc) - * - * @see com.sun.jna.Structure#getFieldOrder() - */ - protected List getFieldOrder() { - return Arrays.asList(new String[] { "dbcd_size", "dbcd_devicetype", - "dbcd_reserved", "dbcd_devnode" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } @@ -257,6 +251,8 @@ * The Class DEV_BROADCAST_VOLUME. */ public class DEV_BROADCAST_VOLUME extends Structure { + public static final List FIELDS = createFieldsOrder("dbcv_size", "dbcv_devicetype", + "dbcv_reserved", "dbcv_unitmask", "dbcv_flags"); /** The dbcv_size. */ public int dbcv_size = size(); @@ -277,12 +273,12 @@ * Instantiates a new dev broadcast volume. */ public DEV_BROADCAST_VOLUME() { - // TODO Auto-generated constructor stub + super(); } /** * Instantiates a new dev broadcast volume. - * + * * @param memory * the memory */ @@ -291,14 +287,9 @@ read(); } - /* - * (non-Javadoc) - * - * @see com.sun.jna.Structure#getFieldOrder() - */ - protected List getFieldOrder() { - return Arrays.asList(new String[] { "dbcv_size", "dbcv_devicetype", - "dbcv_reserved", "dbcv_unitmask", "dbcv_flags" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } @@ -312,6 +303,7 @@ * The Class DEV_BROADCAST_PORT. */ public class DEV_BROADCAST_PORT extends Structure { + public static final List FIELDS = createFieldsOrder("dbcp_size", "dbcp_devicetype", "dbcp_reserved", "dbcp_name"); /** The dbcp_size. */ public int dbcp_size = size(); @@ -329,12 +321,12 @@ * Instantiates a new dev broadcast port. */ public DEV_BROADCAST_PORT() { - // TODO Auto-generated constructor stub + super(); } /** * Instantiates a new dev broadcast port. - * + * * @param memory * the memory */ @@ -343,14 +335,9 @@ read(); } - /* - * (non-Javadoc) - * - * @see com.sun.jna.Structure#getFieldOrder() - */ - protected List getFieldOrder() { - return Arrays.asList(new String[] { "dbcp_size", "dbcp_devicetype", - "dbcp_reserved", "dbcp_name" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } @@ -358,6 +345,8 @@ * The Class DEV_BROADCAST_NET. */ public class DEV_BROADCAST_NET extends Structure { + public static final List FIELDS = createFieldsOrder("dbcn_size", "dbcn_devicetype", + "dbcn_reserved", "dbcn_resource", "dbcn_flags"); /** The dbcn_size. */ public int dbcn_size = size(); @@ -378,12 +367,12 @@ * Instantiates a new dev broadcast net. */ public DEV_BROADCAST_NET() { - // TODO Auto-generated constructor stub + super(); } /** * Instantiates a new dev broadcast net. - * + * * @param memory * the memory */ @@ -392,14 +381,9 @@ read(); } - /* - * (non-Javadoc) - * - * @see com.sun.jna.Structure#getFieldOrder() - */ - protected List getFieldOrder() { - return Arrays.asList(new String[] { "dbcn_size", "dbcn_devicetype", - "dbcn_reserved", "dbcn_resource", "dbcn_flags" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } @@ -407,6 +391,8 @@ * The Class DEV_BROADCAST_DEVICEINTERFACE. */ public class DEV_BROADCAST_DEVICEINTERFACE extends Structure { + public static final List FIELDS = createFieldsOrder("dbcc_size", "dbcc_devicetype", + "dbcc_reserved", "dbcc_classguid", "dbcc_name"); /** The dbcc_size. */ public int dbcc_size; @@ -427,12 +413,12 @@ * Instantiates a new dev broadcast deviceinterface. */ public DEV_BROADCAST_DEVICEINTERFACE() { - // TODO Auto-generated constructor stub + super(); } /** * Dev broadcast hdr. - * + * * @param pointer * the pointer */ @@ -442,7 +428,7 @@ /** * Instantiates a new dev broadcast deviceinterface. - * + * * @param memory * the memory */ @@ -457,21 +443,16 @@ /** * Gets the dbcc_name. - * + * * @return the dbcc_name */ public String getDbcc_name() { return Native.toString(this.dbcc_name); } - /* - * (non-Javadoc) - * - * @see com.sun.jna.Structure#getFieldOrder() - */ - protected List getFieldOrder() { - return Arrays.asList(new String[] { "dbcc_size", "dbcc_devicetype", - "dbcc_reserved", "dbcc_classguid", "dbcc_name" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } @@ -479,6 +460,9 @@ * The Class DEV_BROADCAST_HANDLE. */ public class DEV_BROADCAST_HANDLE extends Structure { + public static final List FIELDS = createFieldsOrder("dbch_size", "dbch_devicetype", + "dbch_reserved", "dbch_handle", "dbch_hdevnotify", + "dbch_eventguid", "dbch_nameoffset", "dbch_data"); /** The dbch_size. */ public int dbch_size = size(); @@ -508,12 +492,12 @@ * Instantiates a new dev broadcast handle. */ public DEV_BROADCAST_HANDLE() { - // TODO Auto-generated constructor stub + super(); } /** * Instantiates a new dev broadcast handle. - * + * * @param memory * the memory */ @@ -522,15 +506,9 @@ read(); } - /* - * (non-Javadoc) - * - * @see com.sun.jna.Structure#getFieldOrder() - */ - protected List getFieldOrder() { - return Arrays.asList(new String[] { "dbch_size", "dbch_devicetype", - "dbch_reserved", "dbch_handle", "dbch_hdevnotify", - "dbch_eventguid", "dbch_nameoffset", "dbch_data" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Ddeml.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Ddeml.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Ddeml.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Ddeml.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,2730 @@ +/* + * 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.Native; +import com.sun.jna.Pointer; +import com.sun.jna.PointerType; +import com.sun.jna.Structure; +import com.sun.jna.platform.win32.BaseTSD.DWORD_PTR; +import com.sun.jna.platform.win32.BaseTSD.ULONG_PTR; +import com.sun.jna.platform.win32.WinDef.HWND; +import com.sun.jna.platform.win32.WinDef.PVOID; +import com.sun.jna.win32.StdCallLibrary; +import com.sun.jna.win32.W32APIOptions; +import java.util.List; +import static com.sun.jna.Structure.createFieldsOrder; +import com.sun.jna.platform.win32.WinDef.BOOL; +import com.sun.jna.platform.win32.WinDef.DWORD; +import com.sun.jna.platform.win32.WinDef.DWORDByReference; +import com.sun.jna.platform.win32.WinDef.LPARAM; +import com.sun.jna.platform.win32.WinDef.UINT; +import com.sun.jna.platform.win32.WinDef.UINT_PTR; +import com.sun.jna.platform.win32.WinDef.WPARAM; +import com.sun.jna.platform.win32.WinNT.HANDLE; +import com.sun.jna.platform.win32.WinNT.SECURITY_QUALITY_OF_SERVICE; +import com.sun.jna.win32.W32APITypeMapper; + +/** + * Ported from Ddeml.h. Microsoft Windows SDK 7.1. + * + *

    Bindings for the DDEML - Dynamic Data Exchange Management Library (DDEML)

    + * + * @see MSDN: About the DDEML + */ +public interface Ddeml extends StdCallLibrary { + + Ddeml INSTANCE = Native.loadLibrary("user32", Ddeml.class, W32APIOptions.DEFAULT_OPTIONS); + + public class HCONVLIST extends PointerType { + }; + + public class HCONV extends PointerType { + }; + + public class HSZ extends PointerType { + }; + + public class HDDEDATA extends PVOID { + }; + + /** + * the following structure is for use with XTYP_WILDCONNECT processing. + */ + public class HSZPAIR extends Structure { + + public static final List FIELDS = createFieldsOrder("service", "topic"); + + public HSZ service; + public HSZ topic; + + public HSZPAIR() { + } + + public HSZPAIR(HSZ service, HSZ topic) { + this.service = service; + this.topic = topic; + } + + @Override + protected List getFieldOrder() { + return FIELDS; + } + } + + /** + * The following structure is used by DdeConnect() and DdeConnectList() and + * by XTYP_CONNECT and XTYP_WILDCONNECT callbacks. + */ + public class CONVCONTEXT extends Structure { + + public static final List FIELDS = createFieldsOrder( + "cb", "wFlags", "wCountryID", "iCodePage", "dwLangID", + "dwSecurity", "qos"); + /** + * set to sizeof(CONVCONTEXT) + */ + public int cb; + /** + * none currently defined. + */ + public int wFlags; + /** + * country/region code for topic/item strings used. + */ + public int wCountryID; + /** + * codepage used for topic/item strings. + */ + public int iCodePage; + /** + * language ID for topic/item strings. + */ + public int dwLangID; + /** + * Private security code. + */ + public int dwSecurity; + /** + * The quality of service a DDE client wants from the system during a + * given conversation. The quality of service level specified lasts for + * the duration of the conversation. It cannot be changed once the + * conversation is started. + */ + public SECURITY_QUALITY_OF_SERVICE qos; + + public CONVCONTEXT() { + } + + public CONVCONTEXT(Pointer p) { + super(p); + } + + @Override + public void write() { + this.cb = size(); + super.write(); + } + + @Override + protected List getFieldOrder() { + return FIELDS; + } + } + + /* The following structure is used by DdeQueryConvInfo(): */ + public class CONVINFO extends Structure { + + public static final List FIELDS = createFieldsOrder( + "cb", "hUser", "hConvPartner", "hszSvcPartner", "hszServiceReq", + "hszTopic", "hszItem", "wFmt", "wType", "wStatus", "wConvst", + "wLastError", "hConvList", "ConvCtxt", "hwnd", "hwndPartner"); + /* sizeof(CONVINFO) */ + public int cb; + /* user specified field */ + public DWORD_PTR hUser; + /* hConv on other end or 0 if non-ddemgr partner */ + public HCONV hConvPartner; + /* app name of partner if obtainable */ + public HSZ hszSvcPartner; + /* AppName requested for connection */ + public HSZ hszServiceReq; + /* Topic name for conversation */ + public HSZ hszTopic; + /* transaction item name or NULL if quiescent */ + public HSZ hszItem; + /* transaction format or NULL if quiescent */ + public int wFmt; + /* XTYP_ for current transaction */ + public int wType; + /* ST_ constant for current conversation */ + public int wStatus; + /* XST_ constant for current transaction */ + public int wConvst; + /* last transaction error. */ + public int wLastError; + /* parent hConvList if this conversation is in a list */ + public HCONVLIST hConvList; + /* conversation context */ + public CONVCONTEXT ConvCtxt; + /* window handle for this conversation */ + public HWND hwnd; + /* partner window handle for this conversation */ + public HWND hwndPartner; + + @Override + public void write() { + this.cb = size(); + super.write(); + } + + @Override + protected List getFieldOrder() { + return FIELDS; + } + } + + /** + * Contains information about the current Dynamic Data Exchange (DDE) + * transaction. A DDE debugging application can use this structure when + * monitoring transactions that the system passes to the DDE callback + * functions of other applications. + */ + public class MONCBSTRUCT extends Structure { + + public static final List FIELDS = createFieldsOrder( + "cb", "dwTime", "hTask", "dwRet", "wType", "wFmt", "hConv", + "hsz1", "hsz2", "hData", "dwData1", "dwData2", "cc", "cbData", + "Data" + ); + + /** + * The structure's size, in bytes. + */ + public int cb; + /** + * The Windows time at which the transaction occurred. Windows time is + * the number of milliseconds that have elapsed since the system was + * booted. + */ + public int dwTime; + /** + * A handle to the task (application instance) containing the DDE + * callback function that received the transaction. + */ + public HANDLE hTask; + /** + * The value returned by the DDE callback function that processed the + * transaction. + */ + public DWORD dwRet; + /** + * The transaction type. + */ + public int wType; + /** + * The format of the data exchanged (if any) during the transaction. + */ + public int wFmt; + /** + * A handle to the conversation in which the transaction took place. + */ + public HCONV hConv; + /** + * A handle to a string. + */ + public HSZ hsz1; + /** + * A handle to a string. + */ + public HSZ hsz2; + /** + * A handle to the data exchanged (if any) during the transaction. + */ + public HDDEDATA hData; + /** + * Additional data. + */ + public ULONG_PTR dwData1; + /** + * Additional data. + */ + public ULONG_PTR dwData2; + /** + * The language information used to share data in different languages. + */ + public CONVCONTEXT cc; + /** + * The amount, in bytes, of data being passed with the transaction. This + * value can be more than 32 bytes. + */ + public int cbData; + /** + * Contains the first 32 bytes of data being passed with the transaction + * (8 * sizeof(DWORD)). + */ + public byte[] Data = new byte[32]; + + @Override + protected List getFieldOrder() { + return FIELDS; + } + } + + /** + *

    + * Contains information about a Dynamic Data Exchange (DDE) conversation. A + * DDE monitoring application can use this structure to obtain information + * about a conversation that has been established or has terminated.

    + * + *

    + * Remarks

    + * + *

    + * Because string handles are local to the process, the hszSvc and hszTopic + * members are global atoms. Similarly, conversation handles are local to + * the instance; therefore, the hConvClient and hConvServer members are + * window handles.

    + * + *

    + * The hConvClient and hConvServer members of the MONCONVSTRUCT structure do + * not hold the same value as would be seen by the applications engaged in + * the conversation. Instead, they hold a globally unique pair of values + * that identify the conversation.

    + */ + public class MONCONVSTRUCT extends Structure { + + public static final List FIELDS = createFieldsOrder( + "cb", "fConnect", "dwTime", "hTask", "hszSvc", "hszTopic", + "hConvClient", "hConvServer" + ); + + /** + * The structure's size, in bytes. + */ + public UINT cb; + /** + * Indicates whether the conversation is currently established. A value + * of TRUE indicates the conversation is established; FALSE indicates it + * is not. + */ + public BOOL fConnect; + /** + * The Windows time at which the conversation was established or + * terminated. Windows time is the number of milliseconds that have + * elapsed since the system was booted. + */ + public DWORD dwTime; + /** + * A handle to a task (application instance) that is a partner in the + * conversation. + */ + public HANDLE hTask; + /** + * A handle to the service name on which the conversation is + * established. + */ + public HSZ hszSvc; + /** + * A handle to the topic name on which the conversation is established. + */ + public HSZ hszTopic; + /** + * A handle to the client conversation. + */ + public HCONV hConvClient; + /** + * A handle to the server conversation. + */ + public HCONV hConvServer; + + @Override + protected List getFieldOrder() { + return FIELDS; + } + } + + /** + * Contains information about the current Dynamic Data Exchange (DDE) error. + * A DDE monitoring application can use this structure to monitor errors + * returned by DDE Management Library functions. + */ + public class MONERRSTRUCT extends Structure { + + public static final List FIELDS = createFieldsOrder( + "cb", "wLastError", "dwTime", "hTask" + ); + + /** + * The structure's size, in bytes. + */ + public int cb; + /** + * The current error. + */ + public int wLastError; + /** + * The Windows time at which the error occurred. Windows time is the + * number of milliseconds that have elapsed since the system was booted. + */ + public int dwTime; + /** + * A handle to the task (application instance) that called the DDE + * function that caused the error. + */ + public HANDLE hTask; + + @Override + protected List getFieldOrder() { + return FIELDS; + } + } + + /** + * Contains information about a Dynamic Data Exchange (DDE) string handle. A + * DDE monitoring application can use this structure when monitoring the + * activity of the string manager component of the DDE Management Library. + */ + public class MONHSZSTRUCT extends Structure { + + public static final List FIELDS = createFieldsOrder( + "cb", "fsAction", "dwTime", "hsz", "hTask", "str" + ); + + /** + * The structure's size, in bytes. + */ + public int cb; + /** + * The action being performed on the string identified by the hsz + * member. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
    ValueMeaning
    MH_CLEANUP (4)An application is freeing its DDE resources, causing the system + * to delete string handles the application had created. (The + * application called the DdeUninitialize function.)
    MH_CREATE (1)An application is creating a string handle. (The application + * called the DdeCreateStringHandle function.)
    MH_DELETE (3)An application is deleting a string handle. (The application + * called the DdeFreeStringHandle function.)
    MH_KEEP (2)An application is increasing the usage count of a string handle. + * (The application called the DdeKeepStringHandle function.)
    + */ + public int fsAction; + /** + * The Windows time at which the action specified by the fsAction member + * takes place. Windows time is the number of milliseconds that have + * elapsed since the system was booted. + */ + public int dwTime; + /** + * A handle to the string. Because string handles are local to the + * process, this member is a global atom. + */ + public HSZ hsz; + /** + * A handle to the task (application instance) performing the action on + * the string handle. + */ + public HANDLE hTask; + /** + * String identified by the hsz member. + */ + public byte[] str = new byte[1]; + + @Override + public void write() { + cb = this.calculateSize(true); + super.write(); + } + + @Override + public void read() { + readField("cb"); + allocateMemory(cb); + super.read(); + } + + public String getStr() { + int offset = fieldOffset("str"); + if(W32APITypeMapper.DEFAULT == W32APITypeMapper.UNICODE) { + return getPointer().getWideString(offset); + } else { + return getPointer().getString(offset); + } + } + + @Override + protected List getFieldOrder() { + return FIELDS; + } + } + + /** + * Contains information about a Dynamic Data Exchange (DDE) advise loop. A + * DDE monitoring application can use this structure to obtain information + * about an advise loop that has started or ended. + * + *

    + * Remarks

    + * + *

    + * Because string handles are local to the process, the hszSvc, hszTopic, + * and hszItem members are global atoms.

    + * + *

    + * The hConvClient and hConvServer members of the MONLINKSTRUCT structure do + * not hold the same value as would be seen by the applications engaged in + * the conversation. Instead, they hold a globally unique pair of values + * that identify the conversation.

    + */ + public class MONLINKSTRUCT extends Structure { + + public static final List FIELDS = createFieldsOrder( + "cb", "dwTime", "hTask", "fEstablished", "fNoData", "hszSvc", + "hszTopic", "hszItem", "wFmt", "fServer", "hConvServer", + "hConvClient" + ); + + /** + * The structure's size, in bytes. + */ + public int cb; + /** + * The Windows time at which the advise loop was started or ended. + * Windows time is the number of milliseconds that have elapsed since + * the system was booted. + */ + public int dwTime; + /** + * A handle to a task (application instance) that is a partner in the + * advise loop. + */ + public HANDLE hTask; + /** + * Indicates whether an advise loop was successfully established. A + * value of TRUE indicates an advise loop was established; FALSE + * indicates it was not. + */ + public BOOL fEstablished; + /** + * Indicates whether the XTYPF_NODATA flag is set for the advise loop. A + * value of TRUE indicates the flag is set; FALSE indicates it is not. + */ + public BOOL fNoData; + /** + * A handle to the service name of the server in the advise loop. + */ + public HSZ hszSvc; + /** + * A handle to the topic name on which the advise loop is established. + */ + public HSZ hszTopic; + /** + * A handle to the item name that is the subject of the advise loop. + */ + public HSZ hszItem; + /** + * The format of the data exchanged (if any) during the advise loop. + */ + public int wFmt; + /** + * Indicates whether the link notification came from the server. A value + * of TRUE indicates the notification came from the server; FALSE + * indicates otherwise. + */ + public BOOL fServer; + /** + * A handle to the server conversation. + */ + public HCONV hConvServer; + /** + * A handle to the client conversation. + */ + public HCONV hConvClient; + + @Override + protected List getFieldOrder() { + return FIELDS; + } + } + + public class MONMSGSTRUCT extends Structure { + + public static final List FIELDS = createFieldsOrder( + "cb", "hwndTo", "dwTime", "hTask", "wMsg", "wParam", "lParam", + "dmhd" + ); + + /** + * The structure's size, in bytes. + */ + public int cb; + /** + * A handle to the window that receives the DDE message. + */ + public HWND hwndTo; + /** + * The Windows time at which the message was sent or posted. Windows + * time is the number of milliseconds that have elapsed since the system + * was booted. + */ + public int dwTime; + /** + * A handle to the task (application instance) containing the window + * that receives the DDE message. + */ + public HANDLE hTask; + /** + * The identifier of the DDE message. + */ + public int wMsg; + /** + * The wParam parameter of the DDE message. + */ + public WPARAM wParam; + /** + * The lParam parameter of the DDE message. + */ + public LPARAM lParam; + /** + * Additional information about the DDE message. + */ + public DDEML_MSG_HOOK_DATA dmhd; + + @Override + protected List getFieldOrder() { + return FIELDS; + } + } + + public class DDEML_MSG_HOOK_DATA extends Structure { + + public static final List FIELDS = createFieldsOrder( + "uiLo", "uiHi", "cbData", "Data" + ); + + /** + * The unpacked low-order word of the lParam parameter associated with + * the DDE message. + */ + public UINT_PTR uiLo; + /** + * The unpacked high-order word of the lParam parameter associated with + * the DDE message. + */ + public UINT_PTR uiHi; + /** + * The amount of data being passed with the message, in bytes. This + * value can be greater than 32. + */ + public int cbData; + /** + * The first 32 bytes of data being passed with the message (8 * + * sizeof(DWORD)). + */ + public byte[] Data = new byte[32]; + + @Override + protected List getFieldOrder() { + return FIELDS; + } + } + + /* conversation states (usState) */ + /* quiescent states */ + public int XST_NULL = 0; + public int XST_INCOMPLETE = 1; + public int XST_CONNECTED = 2; + /* mid-initiation states */ + public int XST_INIT1 = 3; + public int XST_INIT2 = 4; + /* active conversation states */ + public int XST_REQSENT = 5; + public int XST_DATARCVD = 6; + public int XST_POKESENT = 7; + public int XST_POKEACKRCVD = 8; + public int XST_EXECSENT = 9; + public int XST_EXECACKRCVD = 10; + public int XST_ADVSENT = 11; + public int XST_UNADVSENT = 12; + public int XST_ADVACKRCVD = 13; + public int XST_UNADVACKRCVD = 14; + public int XST_ADVDATASENT = 15; + public int XST_ADVDATAACKRCVD = 16; + + /* used in LOWORD(dwData1) of XTYP_ADVREQ callbacks... */ + public int CADV_LATEACK = 0xFFFF; + + /* conversation status bits (fsStatus) */ + public int ST_CONNECTED = 0x0001; + public int ST_ADVISE = 0x0002; + public int ST_ISLOCAL = 0x0004; + public int ST_BLOCKED = 0x0008; + public int ST_CLIENT = 0x0010; + public int ST_TERMINATED = 0x0020; + public int ST_INLIST = 0x0040; + public int ST_BLOCKNEXT = 0x0080; + public int ST_ISSELF = 0x0100; + + /* DDE constants for wStatus field */ + public int DDE_FACK = 0x8000; + public int DDE_FBUSY = 0x4000; + public int DDE_FDEFERUPD = 0x4000; + public int DDE_FACKREQ = 0x8000; + public int DDE_FRELEASE = 0x2000; + public int DDE_FREQUESTED = 0x1000; + public int DDE_FAPPSTATUS = 0x00ff; + public int DDE_FNOTPROCESSED = 0x0000; + + public int DDE_FACKRESERVED = ~(DDE_FACK | DDE_FBUSY | DDE_FAPPSTATUS); + public int DDE_FADVRESERVED = ~(DDE_FACKREQ | DDE_FDEFERUPD); + public int DDE_FDATRESERVED = ~(DDE_FACKREQ | DDE_FRELEASE | DDE_FREQUESTED); + public int DDE_FPOKRESERVED = ~(DDE_FRELEASE); + + /* message filter hook types */ + public int MSGF_DDEMGR = 0x8001; + + /* codepage constants */ + /** default codepage for windows & old DDE convs. */ + public int CP_WINANSI = 1004; + /** default codepage for usage from java */ + public int CP_WINUNICODE = 1200; + public int CP_WINNEUTRAL = CP_WINUNICODE; + + /* transaction types */ + /* CBR_BLOCK will not work */ + public int XTYPF_NOBLOCK = 0x0002; + /* DDE_FDEFERUPD */ + public int XTYPF_NODATA = 0x0004; + /* DDE_FACKREQ */ + public int XTYPF_ACKREQ = 0x0008; + + public int XCLASS_MASK = 0xFC00; + public int XCLASS_BOOL = 0x1000; + public int XCLASS_DATA = 0x2000; + public int XCLASS_FLAGS = 0x4000; + public int XCLASS_NOTIFICATION = 0x8000; + + /** + * A Dynamic Data Exchange (DDE) callback function, DdeCallback, receives + * the XTYP_ERROR transaction when a critical error occurs. + * + *

    + * Used Parameters

    + *
    + *
    uType
    The transaction type.
    + *
    hconv
    A handle to the conversation associated with the error. + * This parameter is NULL if the error is not associated with a + * conversation.
    + *
    dwData1
    The error code in the low-order word. Currently, only + * the following error code is supported. + * + * + * + *
    ValueMeaning
    DMLERR_LOW_MEMORYMemory is low; advise, poke, or execute + * data may be lost, or the system may fail.
    + *
    + *
    + * + *

    + * Remarks

    + * + *

    + * An application cannot block this transaction type; the CBR_BLOCK return + * code is ignored. The Dynamic Data Exchange Management Library (DDEML) + * attempts to free memory by removing noncritical resources. An application + * that has blocked conversations should unblock them. + *

    + */ + public int XTYP_ERROR = 0x0000 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK; + /** + * Informs the client that the value of the data item has changed. The + * Dynamic Data Exchange (DDE) client callback function, DdeCallback, + * receives this transaction after establishing an advise loop with a + * server. + * + *

    Used Parameters

    + *
    + *
    uType
    The transaction type.
    + *
    uFmt
    The format atom of the data sent from the server.
    + *
    hconv
    A handle to the conversation.
    + *
    hsz1
    A handle to the topic name.
    + *
    hsz2
    A handle to the item name.
    + *
    hdata
    A handle to the data associated with the topic name and + * item name pair. This parameter is NULL if the client specified the + * XTYPF_NODATA flag when it requested the advise loop.
    + *
    + * + *

    Return value

    + * + *

    + * A DDE callback function should return DDE_FACK if it processes this + * transaction, DDE_FBUSY if it is too busy to process this transaction, or + * DDE_FNOTPROCESSED if it rejects this transaction.

    + *

    + * Remarks

    + * + *

    An application must not free the data handle obtained during this + * transaction. An application must, however, copy the data associated with + * the data handle if the application must process the data after the + * callback function returns. An application can use the DdeGetData function + * to copy the data.

    + */ + public int XTYP_ADVDATA = 0x0010 | XCLASS_FLAGS; + /** + * The XTYP_ADVREQ transaction informs the server that an advise transaction + * is outstanding on the specified topic name and item name pair and that + * data corresponding to the topic name and item name pair has changed. The + * system sends this transaction to the Dynamic Data Exchange (DDE) callback + * function, DdeCallback, after the server calls the DdePostAdvise function. + * + *

    Used Parameters

    + *
    + *
    uType
    The transaction type.
    + *
    uFmt
    The format in which the data should be submitted to the client.
    + *
    hconv
    A handle to the conversation.
    + *
    hsz1
    A handle to the topic name.
    + *
    hsz2
    A handle to the item name that has changed.
    + *
    dwData1
    The count, in the low-order word, of XTYP_ADVREQ + * transactions that remain to be processed on the same topic, item, and + * format name set within the context of the current call to the + * DdePostAdvise function. The count is zero if the current XTYP_ADVREQ + * transaction is the last one. A server can use this count to determine + * whether to create an HDATA_APPOWNED data handle to the advise data. + *

    + * The low-order word is set to CADV_LATEACK if the DDEML issued the + * XTYP_ADVREQ transaction because of a late-arriving DDE_ACK message from a + * client being outrun by the server. + *

    + * The high-order word is not used.
    + *
    + * + *

    Return value

    + *

    + * The server should first call the DdeCreateDataHandle function to create a + * data handle that identifies the changed data and then return the handle. + * The server should return NULL if it is unable to complete the + * transaction.

    + *

    + * Remarks

    + * + *

    + * A server cannot block this transaction type; the CBR_BLOCK return code is + * ignored.

    + */ + public int XTYP_ADVREQ = 0x0020 | XCLASS_DATA | XTYPF_NOBLOCK; + /** + * A client uses the XTYP_ADVSTART transaction to establish an advise loop + * with a server. A Dynamic Data Exchange (DDE) server callback function, + * DdeCallback, receives this transaction when a client specifies + * XTYP_ADVSTART as the wType parameter of the DdeClientTransaction + * function. + * + *

    Used Parameters

    + *
    + *
    uType
    The transaction type.
    + *
    uFmt
    The data format requested by the client.
    + *
    hconv
    A handle to the conversation.
    + *
    hsz1
    A handle to the topic name.
    + *
    hsz2
    A handle to the item name.
    + *
    + * + *

    Return value

    + *

    + * A server callback function should return TRUE to allow an advise loop on + * the specified topic name and item name pair, or FALSE to deny the advise + * loop. If the callback function returns TRUE, any subsequent calls to the + * DdePostAdvise function by the server on the same topic name and item name + * pair causes the system to send XTYP_ADVREQ transactions to the server. + *

    + *

    Remarks

    + *

    + * If a client requests an advise loop on a topic name, item name, and data + * format for an advise loop that is already established, the Dynamic Data + * Exchange Management Library (DDEML) does not create a duplicate advise + * loop but instead alters the advise loop flags (XTYPF_ACKREQ and + * XTYPF_NODATA) to match the latest request.

    + *

    This transaction is filtered if the server application specified the + * CBF_FAIL_ADVISES flag in the DdeInitialize function.

    + */ + public int XTYP_ADVSTART = 0x0030 | XCLASS_BOOL; + /** + * A client uses the XTYP_ADVSTOP transaction to end an advise loop with a + * server. A Dynamic Data Exchange (DDE) server callback function, + * DdeCallback, receives this transaction when a client specifies + * XTYP_ADVSTOP in the DdeClientTransaction function. + * + *

    Used Parameters

    + *
    + *
    uType
    The transaction type.
    + *
    uFmt
    The data format requested by the client.
    + *
    hconv
    A handle to the conversation.
    + *
    hsz1
    A handle to the topic name.
    + *
    hsz2
    A handle to the item name.
    + *
    + *

    Remarks

    + *

    + * This transaction is filtered if the server application specified the + * CBF_FAIL_ADVISES flag in the DdeInitialize function.

    + */ + public int XTYP_ADVSTOP = 0x0040 | XCLASS_NOTIFICATION; + /** + * A client uses the XTYP_EXECUTE transaction to send a command string to + * the server. A Dynamic Data Exchange (DDE) server callback function, + * DdeCallback, receives this transaction when a client specifies + * XTYP_EXECUTE in the DdeClientTransaction function. + * + *

    Used Parameters

    + *
    + *
    uType
    The transaction type.
    + *
    hconv
    A handle to the conversation.
    + *
    hsz1
    A handle to the topic name.
    + *
    hdata
    A handle to the command string.
    + *
    + * + *

    Return value

    + * + *

    + * A server callback function should return DDE_FACK if it processes this + * transaction, DDE_FBUSY if it is too busy to process this transaction, or + * DDE_FNOTPROCESSED if it rejects this transaction.

    + * + *

    Remarks

    + * + *

    + * This transaction is filtered if the server application specified the + * CBF_FAIL_EXECUTES flag in the DdeInitialize function.

    + * + *

    + * An application must free the data handle obtained during this + * transaction. An application must, however, copy the command string + * associated with the data handle if the application must process the + * string after the callback function returns. An application can use the + * DdeGetData function to copy the data.

    + * + *

    + * Because most client applications expect a server application to perform + * an XTYP_EXECUTE transaction synchronously, a server should attempt to + * perform all processing of the XTYP_EXECUTE transaction either from within + * the DDE callback function or by returning the CBR_BLOCK return code. If + * the hdata parameter is a command that instructs the server to terminate, + * the server should do so after processing the XTYP_EXECUTE + * transaction.

    + */ + public int XTYP_EXECUTE = 0x0050 | XCLASS_FLAGS; + /** + * A client uses the XTYP_CONNECT transaction to establish a conversation. A + * Dynamic Data Exchange (DDE) server callback function, DdeCallback, + * receives this transaction when a client specifies a service name that the + * server supports (and a topic name that is not NULL) in a call to the + * DdeConnect function. + * + *

    Used Parameters

    + *
    + *
    uType
    The transaction type.
    + *
    hsz1
    A handle to the topic name.
    + *
    hsz2
    A handle to the service name.
    + *
    dwData1
    A pointer to a CONVCONTEXT structure that contains + * context information for the conversation. If the client is not a DDEML + * application, this parameter is 0.
    + *
    dwData2
    Specifies whether the client is the same application + * instance as the server. If the parameter is 1, the client is the same + * instance. If the parameter is 0, the client is a different instance. + *
    + *
    + * + *

    Return value

    + * + *

    + * A server callback function should return TRUE to allow the client to + * establish a conversation on the specified service name and topic name + * pair, or the function should return FALSE to deny the conversation. If + * the callback function returns TRUE and a conversation is successfully + * established, the system passes the conversation handle to the server by + * issuing an XTYP_CONNECT_CONFIRM transaction to the server's callback + * function (unless the server specified the CBF_SKIP_CONNECT_CONFIRMS flag + * in the DdeInitialize function).

    + * + *

    Remarks

    + * + *

    + * This transaction is filtered if the server application specified the + * CBF_FAIL_CONNECTIONS flag in the DdeInitialize function.

    + *

    + * A server cannot block this transaction type; the CBR_BLOCK return code is + * ignored.

    + */ + public int XTYP_CONNECT = 0x0060 | XCLASS_BOOL | XTYPF_NOBLOCK; + /** + * A Dynamic Data Exchange (DDE) server callback function, DdeCallback, + * receives the XTYP_CONNECT_CONFIRM transaction to confirm that a + * conversation has been established with a client and to provide the server + * with the conversation handle. The system sends this transaction as a + * result of a previous XTYP_CONNECT or XTYP_WILDCONNECT transaction. + * + *

    Used Parameters

    + *
    + *
    uType
    The transaction type.
    + *
    hconv
    A handle to the new conversation.
    + *
    hsz1
    A handle to the topic name on which the conversation has been established.
    + *
    hsz2
    A handle to the service name on which the conversation has been established.
    + *
    dwData2
    Specifies whether the client is the same application + * instance as the server. If the parameter is 1, the client is the same + * instance. If the parameter is 0, the client is a different instance. + *
    + *
    + * + *

    Remarks

    + * + *

    + * This transaction is filtered if the server application specified the CBF_SKIP_CONNECT_CONFIRMS flag in the DdeInitialize function. + *

    + *

    + * A server cannot block this transaction type; the CBR_BLOCK return code is ignored. + *

    + */ + public int XTYP_CONNECT_CONFIRM = 0x0070 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK; + /** + * A Dynamic Data Exchange (DDE) client callback function, DdeCallback, + * receives the XTYP_XACT_COMPLETE transaction when an asynchronous + * transaction, initiated by a call to the DdeClientTransaction function, + * has completed. + * + *

    Used Parameters

    + *
    + *
    uType
    The transaction type.
    + *
    uFmt
    The format of the data associated with the completed transaction (if applicable) or NULL if no data was exchanged during the transaction.
    + *
    hConv
    A handle to the conversation.
    + *
    hsz1
    A handle to the topic name involved in the completed transaction.
    + *
    hsz2
    A handle to the item name involved in the completed transaction.
    + *
    hdata
    A handle to the data involved in the completed transaction, if applicable. If the transaction was successful but involved no data, this parameter is TRUE. This parameter is NULL if the transaction was unsuccessful.
    + *
    dwData1
    The transaction identifier of the completed transaction.
    + *
    dwData2
    Any applicable DDE_ status flags in the low word. This parameter provides support for applications dependent on DDE_APPSTATUS bits. It is recommended that applications no longer use these bits — they may not be supported in future versions of the DDEML.
    + *
    + * + *

    Remarks

    + * + *

    + * An application must not free the data handle obtained during this + * transaction. An application must, however, copy the data associated with + * the data handle if the application must process the data after the + * callback function returns. An application can use the DdeGetData function + * to copy the data. + *

    + */ + public int XTYP_XACT_COMPLETE = 0x0080 | XCLASS_NOTIFICATION; + /** + * A client uses the XTYP_POKE transaction to send unsolicited data to the + * server. A Dynamic Data Exchange (DDE) server callback function, + * DdeCallback, receives this transaction when a client specifies XTYP_POKE + * in the DdeClientTransaction function. + * + *

    Used Parameters

    + *
    + *
    uType
    The transaction type.
    + *
    uFmt
    The format of the data sent from the server.
    + *
    hConv
    A handle to the conversation.
    + *
    hsz1
    A handle to the topic name.
    + *
    hsz2
    A handle to the service name.
    + *
    hdata
    A handle to the data that the client is sending to the server.
    + *
    + * + *

    Return value

    + * + *

    + * A server callback function should return the DDE_FACK flag if it + * processes this transaction, the DDE_FBUSY flag if it is too busy to + * process this transaction, or the DDE_FNOTPROCESSED flag if it rejects + * this transaction.

    + * + *

    Remarks

    + * + *

    + * This transaction is filtered if the server application specified the CBF_FAIL_POKES flag in the DdeInitialize function. + *

    + */ + public int XTYP_POKE = 0x0090 | XCLASS_FLAGS; + /** + * A Dynamic Data Exchange (DDE) callback function, DdeCallback, receives + * the XTYP_REGISTER transaction type whenever a Dynamic Data Exchange + * Management Library (DDEML) server application uses the DdeNameService + * function to register a service name, or whenever a non-DDEML application + * that supports the System topic is started. + * + *

    Used Parameters

    + *
    + *
    uType
    The transaction type.
    + *
    hsz1
    A handle to the base service name being registered. + *
    + *
    hsz2
    A handle to the instance-specific service name being + * registered.
    + *
    + * + * Remarks + *

    + * This transaction is filtered if the application specified the + * CBF_SKIP_REGISTRATIONS flag in the DdeInitialize function.

    + * + *

    + * A application cannot block this transaction type; the CBR_BLOCK return + * code is ignored.

    + * + *

    + * An application should use the hsz1 parameter to add the service name to + * the list of servers available to the user. An application should use the + * hsz2 parameter to identify which application instance has started.

    + */ + public int XTYP_REGISTER = 0x00A0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK; + /** + * A client uses the XTYP_REQUEST transaction to request data from a server. + * A Dynamic Data Exchange (DDE) server callback function, DdeCallback, + * receives this transaction when a client specifies XTYP_REQUEST in the + * DdeClientTransaction function. + * + *

    Used Parameters

    + *
    + *
    uType
    The transaction type.
    + *
    uFmt
    The format in which the server should submit data to the client.
    + *
    hConv
    A handle to the conversation.
    + *
    hsz1
    A handle to the topic name.
    + *
    hsz2
    A handle to the service name.
    + *
    + * + *

    Return value

    + * + *

    + * The server should call the DdeCreateDataHandle function to create a data + * handle that identifies the data and then return the handle. The server + * should return NULL if it is unable to complete the transaction. If the + * server returns NULL, the client will receive a DDE_FNOTPROCESSED + * flag.

    + * + *

    Remarks

    + * + *

    + * This transaction is filtered if the server application specified the + * CBF_FAIL_REQUESTS flag in the DdeInitialize function.

    + *

    + * If responding to this transaction requires lengthy processing, the server + * can return the CBR_BLOCK return code to suspend future transactions on + * the current conversation and then process the transaction asynchronously. + * When the server has finished and the data is ready to pass to the client, + * the server can call the DdeEnableCallback function to resume the + * conversation.

    + */ + public int XTYP_REQUEST = 0x00B0 | XCLASS_DATA; + /** + * An application's Dynamic Data Exchange (DDE) callback function, + * DdeCallback, receives the XTYP_DISCONNECT transaction when the + * application's partner in a conversation uses the DdeDisconnect function + * to terminate the conversation. + * + *

    Used Parameters

    + *
    + *
    uType
    The transaction type.
    + *
    hconv
    A handle to that the conversation was terminated.
    + *
    dwData2
    Specifies whether the client is the same application + * instance as the server. If the parameter is 1, the client is the same + * instance. If the parameter is 0, the client is a different instance. + *
    + *
    + + *

    Remarks

    + * + *

    + * This transaction is filtered if the application specified the + * CBF_SKIP_DISCONNECTS flag in the DdeInitialize function.

    + *

    + * The application can obtain the status of the terminated conversation by + * calling the DdeQueryConvInfo function while processing this transaction. + * The conversation handle becomes invalid after the callback function + * returns.

    + *

    + * An application cannot block this transaction type; the CBR_BLOCK return + * code is ignored.

    + */ + public int XTYP_DISCONNECT = 0x00C0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK; + /** + * A Dynamic Data Exchange (DDE) callback function, DdeCallback, receives + * the XTYP_UNREGISTER transaction whenever a Dynamic Data Exchange + * Management Library (DDEML) server application uses the DdeNameService + * function to unregister a service name, or whenever a non-DDEML + * application that supports the System topic is terminated. + * + *

    + * Used Parameters

    + *
    + *
    uType
    The transaction type.
    + *
    hsz1
    A handle to the base service name being unregistered.
    + *
    hsz2
    A handle to the instance-specific service name being unregistered.
    + *
    + * + *

    + * Remarks

    + * + *

    + * This transaction is filtered if the application specified the + * CBF_SKIP_REGISTRATIONS flag in the DdeInitialize function.

    + *

    + * A application cannot block this transaction type; the CBR_BLOCK return + * code is ignored.

    + *

    + * An application should use the hsz1 parameter to remove the service name + * from the list of servers available to the user. An application should use + * the hsz2 parameter to identify which application instance has + * terminated.

    + */ + public int XTYP_UNREGISTER = 0x00D0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK; + /** + * Enables a client to establish a conversation on each of the server's + * service name and topic name pairs that match the specified service name + * and topic name. A Dynamic Data Exchange (DDE) server callback function, + * DdeCallback, receives this transaction when a client specifies a NULL + * service name, a NULL topic name, or both in a call to the DdeConnect or + * DdeConnectList function. + * + *

    + * Used Parameters

    + *
    + *
    uType
    The transaction type.
    + *
    hsz1
    A handle to the topic name. If this parameter is NULL, + * the client is requesting a conversation on all topic names that the + * server supports.
    + *
    hsz2
    A handle to the service name. If this parameter is NULL, + * the client is requesting a conversation on all service names that the + * server supports.
    + *
    dwData1
    A pointer to a CONVCONTEXT structure that contains + * context information for the conversation. If the client is not a DDEML + * application, this parameter is set to 0.
    + *
    dwData2
    Specifies whether the client is the same application + * instance as the server. If the parameter is 1, the client is same + * instance. If the parameter is 0, the client is a different instance.
    + *
    + * + *

    + * Return value

    + * + *

    + * The server should return a data handle that identifies an array of + * HSZPAIR structures. The array should contain one structure for each + * service-name and topic-name pair that matches the service-name and + * topic-name pair requested by the client. The array must be terminated by + * a NULL string handle. The system sends the XTYP_CONNECT_CONFIRM + * transaction to the server to confirm each conversation and to pass the + * conversation handles to the server. The server will not receive these + * confirmations if it specified the CBF_SKIP_CONNECT_CONFIRMS flag in the + * DdeInitialize function.

    + *

    + * The server should return NULL to refuse the XTYP_WILDCONNECT transaction. + *

    + * + *

    + * Remarks

    + * + *

    + * This transaction is filtered if the server application specified the + * CBF_FAIL_CONNECTIONS flag in the DdeInitialize function.

    + *

    + * A server cannot block this transaction type; the CBR_BLOCK return code is + * ignored.

    + */ + public int XTYP_WILDCONNECT = 0x00E0 | XCLASS_DATA | XTYPF_NOBLOCK; + /** + * A Dynamic Data Exchange (DDE) debugger's DDE callback function, + * DdeCallback, receives the XTYP_MONITOR transaction whenever a DDE event + * occurs in the system. To receive this transaction, an application must + * specify the APPCLASS_MONITOR value when it calls the DdeInitialize + * function. + * + *

    + * Used Parameters

    + *
    + *
    uType
    The transaction type.
    + *
    hdata
    A handle to a DDE object that contains information + * about the DDE event. The application should use the DdeAccessData + * function to obtain a pointer to the object.
    + *
    dwData2
    The DDE event. This parameter can be one of the + * following values. + * + * + * + * + * + * + * + * + * + *
    ValueMeaning
    MF_CALLBACKSThe system sent a transaction to a DDE + * callback function. The DDE object contains a MONCBSTRUCT structure that + * provides information about the transaction.
    MF_CONVA DDE conversation was established or terminated. + * The DDE object contains a MONCONVSTRUCT structure that provides + * information about the conversation.
    MF_ERRORSA DDE error occurred. The DDE object contains a + * MONERRSTRUCT structure that provides information about the + * error.
    MF_HSZ_INFOA DDE application created, freed, or + * incremented the usage count of a string handle, or a string handle was + * freed as a result of a call to the DdeUninitialize function. The DDE + * object contains a MONHSZSTRUCT structure that provides information about + * the string handle.
    MF_LINKSA DDE application started or stopped an advise + * loop. The DDE object contains a MONLINKSTRUCT structure that provides + * information about the advise loop.
    MF_POSTMSGSThe system or an application posted a DDE + * message. The DDE object contains a MONMSGSTRUCT structure that provides + * information about the message.
    MF_SENDMSGSThe system or an application sent a DDE + * message. The DDE object contains a MONMSGSTRUCT structure that provides + * information about the message.
    + *
    + *
    + * + *

    + * Return value

    + * + *

    + * If the callback function processes this transaction, it should return 0. + *

    + */ + public int XTYP_MONITOR = 0x00F0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK; + + public int XTYP_MASK = 0x00F0; + /* shift to turn XTYP_ into an index */ + public int XTYP_SHIFT = 4; + + /** Timeout constants for asynchronous requests */ + public int TIMEOUT_ASYNC = 0xFFFFFFFF; + + /** Pseudo Transaction ID constant for the synchronous transaction */ + public int QID_SYNC = 0xFFFFFFFF; + + /* public strings used in DDE */ + public String SZDDESYS_TOPIC = "System"; + public String SZDDESYS_ITEM_TOPICS = "Topics"; + public String SZDDESYS_ITEM_SYSITEMS = "SysItems"; + public String SZDDESYS_ITEM_RTNMSG = "ReturnMessage"; + public String SZDDESYS_ITEM_STATUS = "Status"; + public String SZDDESYS_ITEM_FORMATS = "Formats"; + public String SZDDESYS_ITEM_HELP = "Help"; + public String SZDDE_ITEM_ITEMLIST = "TopicItemList"; + + public int DMLERR_NO_ERROR = 0; /* must be 0 */ + + public int DMLERR_FIRST = 0x4000; + + /** + * A request for a synchronous advise transaction has timed out. + */ + public int DMLERR_ADVACKTIMEOUT = 0x4000; + /** + * The response to the transaction caused the DDE_FBUSY flag to be set. + */ + public int DMLERR_BUSY = 0x4001; + /** + * A request for a synchronous data transaction has timed out. + */ + public int DMLERR_DATAACKTIMEOUT = 0x4002; + /** + * A DDEML function was called without first calling the DdeInitialize + * function, or an invalid instance identifier was passed to a DDEML + * function. + */ + public int DMLERR_DLL_NOT_INITIALIZED = 0x4003; + /** + * An application initialized as APPCLASS_MONITOR has attempted to perform a + * DDE transaction, or an application initialized as APPCMD_CLIENTONLY has + * attempted to perform server transactions. + */ + public int DMLERR_DLL_USAGE = 0x4004; + /** + * A request for a synchronous execute transaction has timed out. + */ + public int DMLERR_EXECACKTIMEOUT = 0x4005; + /** + * A parameter failed to be validated by the DDEML. Some of the possible + * causes follow: + * + *
      + *
    • The application used a data handle initialized with a different item + * name handle than was required by the transaction.
    • + *
    • The application used a data handle that was initialized with a + * different clipboard data format than was required by the + * transaction.
    • + *
    • The application used a client-side conversation handle with a + * server-side function or vice versa.
    • + *
    • The application used a freed data handle or string handle.
    • + *
    • More than one instance of the application used the same object.
    • + *
    + */ + public int DMLERR_INVALIDPARAMETER = 0x4006; + /** + * A DDEML application has created a prolonged race condition (in which the + * server application outruns the client), causing large amounts of memory + * to be consumed. + */ + public int DMLERR_LOW_MEMORY = 0x4007; + /** + * A memory allocation has failed. + */ + public int DMLERR_MEMORY_ERROR = 0x4008; + /** + * A transaction has failed. + */ + public int DMLERR_NOTPROCESSED = 0x4009; + /** + * A client's attempt to establish a conversation has failed. + */ + public int DMLERR_NO_CONV_ESTABLISHED = 0x400a; + /** + * A request for a synchronous poke transaction has timed out. + */ + public int DMLERR_POKEACKTIMEOUT = 0x400b; + /** + * An internal call to the PostMessage function has failed. + */ + public int DMLERR_POSTMSG_FAILED = 0x400c; + /** + * An application instance with a synchronous transaction already in + * progress attempted to initiate another synchronous transaction, or the + * DdeEnableCallback function was called from within a DDEML callback + * function. + */ + public int DMLERR_REENTRANCY = 0x400d; + /** + * A server-side transaction was attempted on a conversation terminated by + * the client, or the server terminated before completing a transaction. + */ + public int DMLERR_SERVER_DIED = 0x400e; + /** + * An internal error has occurred in the DDEML. + */ + public int DMLERR_SYS_ERROR = 0x400f; + /** + * A request to end an advise transaction has timed out. + */ + public int DMLERR_UNADVACKTIMEOUT = 0x4010; + /** + * An invalid transaction identifier was passed to a DDEML function. Once + * the application has returned from an XTYP_XACT_COMPLETE callback, the + * transaction identifier for that callback function is no longer valid. + */ + public int DMLERR_UNFOUND_QUEUE_ID = 0x4011; + + public int DMLERR_LAST = 0x4011; + + public int HDATA_APPOWNED = 0x0001; + + public interface DdeCallback extends StdCallLibrary.StdCallCallback { + PVOID ddeCallback(int wType, int wFmt, HCONV hConv, HSZ hsz1, HSZ hsz2, HDDEDATA hData, ULONG_PTR lData1, ULONG_PTR lData2); + } + + /** + * Prevents the callback function from receiving XTYP_CONNECT transactions + * from the application's own instance. This flag prevents an application + * from establishing a DDE conversation with its own instance. An + * application should use this flag if it needs to communicate with other + * instances of itself but not with itself. + */ + public int CBF_FAIL_SELFCONNECTIONS = 0x00001000; + /** + * Prevents the callback function from receiving XTYP_CONNECT and + * XTYP_WILDCONNECT transactions. + */ + public int CBF_FAIL_CONNECTIONS = 0x00002000; + /** + * Prevents the callback function from receiving XTYP_ADVSTART and + * XTYP_ADVSTOP transactions. The system returns DDE_FNOTPROCESSED to each + * client that sends an XTYP_ADVSTART or XTYP_ADVSTOP transaction to the + * server. + */ + public int CBF_FAIL_ADVISES = 0x00004000; + /** + * Prevents the callback function from receiving XTYP_EXECUTE transactions. + * The system returns DDE_FNOTPROCESSED to a client that sends an + * XTYP_EXECUTE transaction to the server. + */ + public int CBF_FAIL_EXECUTES = 0x00008000; + /** + * Prevents the callback function from receiving XTYP_POKE transactions. The + * system returns DDE_FNOTPROCESSED to a client that sends an XTYP_POKE + * transaction to the server. + */ + public int CBF_FAIL_POKES = 0x00010000; + /** + * Prevents the callback function from receiving XTYP_REQUEST transactions. + * The system returns DDE_FNOTPROCESSED to a client that sends an + * XTYP_REQUEST transaction to the server. + */ + public int CBF_FAIL_REQUESTS = 0x00020000; + /** + * Prevents the callback function from receiving server transactions. The + * system returns DDE_FNOTPROCESSED to each client that sends a transaction + * to this application. This flag is equivalent to combining all CBF_FAIL_ + * flags. + */ + public int CBF_FAIL_ALLSVRXACTIONS = 0x0003f000; + + /** + * Prevents the callback function from receiving XTYP_CONNECT_CONFIRM + * notifications. + */ + public int CBF_SKIP_CONNECT_CONFIRMS = 0x00040000; + /** + * Prevents the callback function from receiving XTYP_REGISTER + * notifications. + */ + public int CBF_SKIP_REGISTRATIONS = 0x00080000; + /** + *Prevents the callback function from receiving XTYP_UNREGISTER + * notifications. + */ + public int CBF_SKIP_UNREGISTRATIONS = 0x00100000; + /** + * Prevents the callback function from receiving XTYP_DISCONNECT + * notifications. + */ + public int CBF_SKIP_DISCONNECTS = 0x00200000; + /** + * Prevents the callback function from receiving any notifications. This + * flag is equivalent to combining all CBF_SKIP_ flags. + */ + public int CBF_SKIP_ALLNOTIFICATIONS = 0x003c0000; + + /** + * Prevents the application from becoming a server in a DDE conversation. + * The application can only be a client. This flag reduces consumption of + * resources by the DDEML. It includes the functionality of the + * CBF_FAIL_ALLSVRXACTIONS + */ + public int APPCMD_CLIENTONLY = 0x00000010; + /** + * Prevents the DDEML from sending XTYP_CONNECT and XTYP_WILDCONNECT + * transactions to the application until the application has created its + * string handles and registered its service names or has turned off + * filtering by a subsequent call to the DdeNameService or DdeInitialize + * function. This flag is always in effect when an application calls + * DdeInitialize for the first time, regardless of whether the application + * specifies the flag. On subsequent calls to DdeInitialize, not specifying + * this flag turns off the application's service-name filters, but + * specifying it turns on the application's service name filters. + */ + public int APPCMD_FILTERINITS = 0x00000020; + public int APPCMD_MASK = 0x00000FF0; + + /** + * Registers the application as a standard (nonmonitoring) DDEML + * application. + */ + public int APPCLASS_STANDARD = 0x00000000; + /** + * Makes it possible for the application to monitor DDE activity in the + * system. This flag is for use by DDE monitoring applications. The + * application specifies the types of DDE activity to monitor by combining + * one or more monitor flags with the APPCLASS_MONITOR flag. + */ + public int APPCLASS_MONITOR = 0x00000001; + public int APPCLASS_MASK = 0x0000000F; + + /** + * Notifies the callback function whenever a DDE application creates, frees, + * or increments the usage count of a string handle or whenever a string + * handle is freed as a result of a call to the DdeUninitialize + * function. + */ + public int MF_HSZ_INFO = 0x01000000; + /** + * Notifies the callback function whenever the system or an application + * sends a DDE message. + */ + public int MF_SENDMSGS = 0x02000000; + /** + * Notifies the callback function whenever the system or an application + * posts a DDE message. + */ + public int MF_POSTMSGS = 0x04000000; + /** + * Notifies the callback function whenever a transaction is sent to any DDE + * callback function in the system. + */ + public int MF_CALLBACKS = 0x08000000; + /** + * Notifies the callback function whenever a DDE error occurs. + */ + public int MF_ERRORS = 0x10000000; + /** + * Notifies the callback function whenever an advise loop is started or + * ended. + */ + public int MF_LINKS = 0x20000000; + /** + * Notifies the callback function whenever a conversation is established or + * terminated. + */ + public int MF_CONV = 0x40000000; + + public int MF_MASK = 0xFF000000; + + public int EC_ENABLEALL = 0; + public int EC_ENABLEONE = ST_BLOCKNEXT; + public int EC_DISABLE = ST_BLOCKED; + public int EC_QUERYWAITING = 2; + + public int DNS_REGISTER = 0x0001; + public int DNS_UNREGISTER = 0x0002; + public int DNS_FILTERON = 0x0004; + public int DNS_FILTEROFF = 0x0008; + + /** + * Registers an application with the Dynamic Data Exchange Management + * Library (DDEML). An application must call this function before calling + * any other Dynamic Data Exchange Management Library (DDEML) function. + * + * @param pidInst The application instance identifier. At initialization, + * this parameter should point to 0. If the function succeeds, this + * parameter points to the instance identifier for the application. This + * value should be passed as the idInst parameter in all other DDEML + * functions that require it. If an application uses multiple instances of + * the DDEML dynamic-link library (DLL), the application should provide a + * different callback function for each instance. + * + *

    If pidInst points to a nonzero value, reinitialization of the DDEML is + * implied. In this case, pidInst must point to a valid application-instance + * identifier.

    + * + * @param fnCallback A pointer to the application-defined DDE callback function. + * This function processes DDE transactions sent by the system. + * For more information, see the DdeCallback callback function. + * + * @param afCmd A set of APPCMD_, CBF_, and MF_ flags. The APPCMD_ flags + * provide special instructions to DdeInitialize. The CBF_ flags specify + * filters that prevent specific types of transactions from reaching the + * callback function. The MF_ flags specify the types of DDE activity that a + * DDE monitoring application monitors. Using these flags enhances the + * performance of a DDE application by eliminating unnecessary calls to the + * callback function. + * + *

    This parameter can be one or more of the following values.

    + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
    ValueMeaning
    + *
    APPCLASS_MONITOR
    + *
    0x00000001L
    + *
    + *
    + *

    + * Makes it possible for the application to monitor DDE activity in the + * system. This flag is for use by DDE monitoring applications. The + * application specifies the types of DDE activity to monitor by combining + * one or more monitor flags with the APPCLASS_MONITOR flag. For details, + * see the following Remarks section.

    + *
    + *
    APPCLASS_STANDARD
    + *
    0x00000000L
    + *
    + *
    + *

    + * Registers the application as a standard (nonmonitoring) DDEML + * application.

    + *
    + *
    APPCMD_CLIENTONLY
    + *
    0x00000010L
    + *
    + *
    + *

    + * Prevents the application from becoming a server in a DDE conversation. + * The application can only be a client. This flag reduces consumption of + * resources by the DDEML. It includes the functionality of the + * CBF_FAIL_ALLSVRXACTIONS flag.

    + *
    + *
    APPCMD_FILTERINITS
    + *
    0x00000020L
    + *
    + *
    + *

    + * Prevents the DDEML from sending XTYP_CONNECT and XTYP_WILDCONNECT + * transactions to the application until the application has created its + * string handles and registered its service names or has turned off + * filtering by a subsequent call to the DdeNameService or DdeInitialize + * function. This flag is always in effect when an application calls + * DdeInitialize for the first time, regardless of whether the application + * specifies the flag. On subsequent calls to DdeInitialize, not specifying + * this flag turns off the application's service-name filters, but + * specifying it turns on the application's service name filters.

    + *
    + *
    CBF_FAIL_ALLSVRXACTIONS
    + *
    0x0003f000
    + *
    + *
    + *

    + * Prevents the callback function from receiving server transactions. The + * system returns DDE_FNOTPROCESSED to each client that sends a transaction + * to this application. This flag is equivalent to combining all CBF_FAIL_ + * flags.

    + *
    + *
    CBF_FAIL_ADVISES
    + *
    0x00004000
    + *
    + *
    + *

    + * Prevents the callback function from receiving XTYP_ADVSTART and + * XTYP_ADVSTOP transactions. The system returns DDE_FNOTPROCESSED to each + * client that sends an XTYP_ADVSTART or XTYP_ADVSTOP transaction to the + * server.

    + *
    + *
    CBF_FAIL_CONNECTIONS
    + *
    0x00002000
    + *
    + *
    + *

    + * Prevents the callback function from receiving XTYP_CONNECT and + * XTYP_WILDCONNECT transactions.

    + *
    + *
    CBF_FAIL_EXECUTES
    + *
    0x00008000
    + *
    + *
    + *

    + * Prevents the callback function from receiving XTYP_EXECUTE transactions. + * The system returns DDE_FNOTPROCESSED to a client that sends an + * XTYP_EXECUTE transaction to the server.

    + *
    + *
    CBF_FAIL_POKES
    + *
    0x00010000
    + *
    + *
    + *

    + * Prevents the callback function from receiving XTYP_POKE transactions. The + * system returns DDE_FNOTPROCESSED to a client that sends an XTYP_POKE + * transaction to the server.

    + *
    + *
    CBF_FAIL_REQUESTS
    + *
    0x00020000
    + *
    + *
    + *

    + * Prevents the callback function from receiving XTYP_REQUEST transactions. + * The system returns DDE_FNOTPROCESSED to a client that sends an + * XTYP_REQUEST transaction to the server.

    + *
    + *
    CBF_FAIL_SELFCONNECTIONS
    + *
    0x00001000
    + *
    + *
    + *

    + * Prevents the callback function from receiving XTYP_CONNECT transactions + * from the application's own instance. This flag prevents an application + * from establishing a DDE conversation with its own instance. An + * application should use this flag if it needs to communicate with other + * instances of itself but not with itself.

    + *
    + *
    CBF_SKIP_ALLNOTIFICATIONS
    + *
    0x003c0000
    + *
    + *
    + *

    + * Prevents the callback function from receiving any notifications. This + * flag is equivalent to combining all CBF_SKIP_ flags.

    + *
    + *
    CBF_SKIP_CONNECT_CONFIRMS
    + *
    0x00040000
    + *
    + *
    + *

    + * Prevents the callback function from receiving XTYP_CONNECT_CONFIRM + * notifications.

    + *
    + *
    CBF_SKIP_DISCONNECTS
    + *
    0x00200000
    + *
    + *
    + *

    + * Prevents the callback function from receiving XTYP_DISCONNECT + * notifications.

    + *
    + *
    CBF_SKIP_REGISTRATIONS
    + *
    0x00080000
    + *
    + *
    + *

    + * Prevents the callback function from receiving XTYP_REGISTER + * notifications.

    + *
    + *
    CBF_SKIP_UNREGISTRATIONS
    + *
    0x00100000
    + *
    + *
    + *

    + * Prevents the callback function from receiving XTYP_UNREGISTER + * notifications.

    + *
    + *
    MF_CALLBACKS
    + *
    0x08000000
    + *
    + *
    + *

    + * Notifies the callback function whenever a transaction is sent to any DDE + * callback function in the system.

    + *
    + *
    MF_CONV
    + *
    0x40000000
    + *
    + *
    + *

    + * Notifies the callback function whenever a conversation is established or + * terminated.

    + *
    + *
    MF_ERRORS
    + *
    0x10000000
    + *
    + *
    + *

    + * Notifies the callback function whenever a DDE error occurs.

    + *
    + *
    MF_HSZ_INFO
    + *
    0x01000000
    + *
    + *
    + *

    + * Notifies the callback function whenever a DDE application creates, frees, + * or increments the usage count of a string handle or whenever a string + * handle is freed as a result of a call to the DdeUninitialize + * function.

    + *
    + *
    MF_LINKS
    + *
    0x20000000
    + *
    + *
    + *

    + * Notifies the callback function whenever an advise loop is started or + * ended.

    + *
    + *
    MF_POSTMSGS
    + *
    0x04000000
    + *
    + *
    + *

    + * Notifies the callback function whenever the system or an application + * posts a DDE message.

    + *
    + *
    MF_SENDMSGS
    + *
    0x02000000
    + *
    + *
    + *

    + * Notifies the callback function whenever the system or an application + * sends a DDE message.

    + *
    + * + * @param ulRes Reserved; must be set to zero. + * @return If the function succeeds, the return value is DMLERR_NO_ERROR. + * + *

    If the function fails, the return value is one of the following values:

    + *
      + *
    • DMLERR_DLL_USAGE
    • + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_SYS_ERROR
    • + *
    + */ + public int DdeInitialize(DWORDByReference pidInst, DdeCallback fnCallback, int afCmd, int ulRes); + + /** + * Frees all Dynamic Data Exchange Management Library (DDEML) resources + * associated with the calling application. + * + * @param idInst The application instance identifier obtained by a previous + * call to the DdeInitialize function. + * + * @return true if function succeeded + */ + public boolean DdeUninitialize(int idInst); + + /** + * Establishes a conversation with all server applications that support the + * specified service name and topic name pair. An application can also use + * this function to obtain a list of conversation handles by passing the + * function an existing conversation handle. The Dynamic Data Exchange + * Management Library removes the handles of any terminated conversations + * from the conversation list. The resulting conversation list contains the + * handles of all currently established conversations that support the + * specified service name and topic name. + * + * @param idInst The application instance identifier obtained by a previous + * call to the DdeInitialize function. + * + * @param hszService A handle to the string that specifies the service name + * of the server application with which a conversation is to be established. + * If this parameter is 0L, the system attempts to establish conversations + * with all available servers that support the specified topic name. + * + * @param hszTopic A handle to the string that specifies the name of the + * topic on which a conversation is to be established. This handle must + * have been created by a previous call to the DdeCreateStringHandle + * function. If this parameter is 0L, the system will attempt to establish + * conversations on all topics supported by the selected server (or servers). + * + * @param hConvList A handle to the conversation list to be enumerated. + * This parameter should be 0L if a new conversation list is to be established. + * + * @param pCC A pointer to the CONVCONTEXT structure that contains + * conversation-context information. If this parameter is NULL, the server + * receives the default CONVCONTEXT structure during the XTYP_CONNECT or + * XTYP_WILDCONNECT transaction. + * + * @return If the function succeeds, the return value is the handle to a + * new conversation list. + * + *

    If the function fails, the return value is 0L. The handle to the old + * conversation list is no longer valid.

    + * + *

    The DdeGetLastError function can be used to get the error code, which + * can be one of the following values:

    + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_NO_CONV_ESTABLISHED
    • + *
    • DMLERR_NO_ERROR
    • + *
    • DMLERR_SYS_ERROR
    • + *
    + */ + public HCONVLIST DdeConnectList(int idInst, HSZ hszService, HSZ hszTopic, + HCONVLIST hConvList, CONVCONTEXT pCC); + + /** + * Retrieves the next conversation handle in the specified conversation list. + * + * @param hConvList A handle to the conversation list. This handle must have + * been created by a previous call to the DdeConnectList function. + * + * @param hConvPrev A handle to the conversation handle previously returned + * by this function. If this parameter is 0L, the function returns the first + * conversation handle in the list. + * + * @return If the list contains any more conversation handles, the return + * value is the next conversation handle in the list; otherwise, it is 0L. + */ + public HCONV DdeQueryNextServer( HCONVLIST hConvList, HCONV hConvPrev); + + /** + * Destroys the specified conversation list and terminates all + * conversations associated with the list. + * + * @param hConvList A handle to the conversation list. This handle must have + * been created by a previous call to the DdeConnectList function. + * + * @return true if the function succeeds, the return value is nonzero. + * + *

    The DdeGetLastError function can be used to get the error code, + * which can be one of the following values:

    + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_NO_ERROR
    • + *
    + */ + public boolean DdeDisconnectList(HCONVLIST hConvList); + + /** + * Establishes a conversation with a server application that supports the + * specified service name and topic name pair. If more than one such server + * exists, the system selects only one. + * + * @param idInst The application instance identifier obtained by a previous + * call to the DdeInitialize function. + * + * @param hszService A handle to the string that specifies the service name + * of the server application with which a conversation is to be established. + * This handle must have been created by a previous call to the + * DdeCreateStringHandle function. If this parameter is 0L, a conversation + * is established with any available server. + * + * @param hszTopic A handle to the string that specifies the name of the + * topic on which a conversation is to be established. This handle must have + * been created by a previous call to DdeCreateStringHandle. If this + * parameter is 0L, a conversation on any topic supported by the selected + * server is established. + * + * @param pCC A pointer to the CONVCONTEXT structure that contains + * conversation context information. If this parameter is NULL, the server + * receives the default CONVCONTEXT structure during the XTYP_CONNECT or + * XTYP_WILDCONNECT transaction. + * + * @return If the function succeeds, the return value is the handle to the + * established conversation. + * + *

    If the function fails, the return value is 0L.

    + * + *

    The DdeGetLastError function can be used to get the error code, which can + * be one of the following values:

    + * + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_NO_CONV_ESTABLISHED
    • + *
    • DMLERR_NO_ERROR
    • + *
    + */ + public HCONV DdeConnect( int idInst, HSZ hszService, HSZ hszTopic, CONVCONTEXT pCC); + + /** + * Terminates a conversation started by either the DdeConnect or + * DdeConnectList function and invalidates the specified conversation + * handle. + * + * @param hConv A handle to the active conversation to be terminated. + * + * @return true if the function succeeds + * + *

    + * The DdeGetLastError function can be used to get the error code, which can + * be one of the following values:

    + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_NO_CONV_ESTABLISHED
    • + *
    • DMLERR_NO_ERROR
    • + *
    + */ + public boolean DdeDisconnect( HCONV hConv); + + /** + * Enables a client Dynamic Data Exchange Management Library (DDEML) + * application to attempt to reestablish a conversation with a service that + * has terminated a conversation with the client. When the conversation is + * reestablished, the Dynamic Data Exchange Management Library (DDEML) + * attempts to reestablish any preexisting advise loops. + * + * @param hConv A handle to the conversation to be reestablished. A client + * must have obtained the conversation handle by a previous call to the + * DdeConnect function or from an XTYP_DISCONNECT transaction. + * @return If the function succeeds, the return value is the handle to the + * reestablished conversation. + * + *

    + * If the function fails, the return value is 0L.

    + * + *

    + * The DdeGetLastError function can be used to get the error code, which can + * be one of the following values:

    + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_NO_CONV_ESTABLISHED
    • + *
    • DMLERR_NO_ERROR
    • + *
    + */ + public HCONV DdeReconnect( HCONV hConv); + + /** + * Retrieves information about a Dynamic Data Exchange (DDE) transaction and about the conversation in which the transaction takes place. + * + * @param hConv A handle to the conversation. + * @param idTransaction The transaction. For asynchronous transactions, this + * parameter should be a transaction identifier returned by the + * DdeClientTransaction function. For synchronous transactions, this + * parameter should be QID_SYNC. + * @param pConvInfo A pointer to the CONVINFO structure that receives + * information about the transaction and conversation. The cb member of the + * CONVINFO structure must specify the length of the buffer allocated for + * the structure. + * @return If the function succeeds, the return value is the number of bytes + * copied into the CONVINFO structure. + * + *

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

    + * + *

    + * The DdeGetLastError function can be used to get the error code, which can + * be one of the following values:

    + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_NO_CONV_ESTABLISHED
    • + *
    • DMLERR_NO_ERROR
    • + *
    • DMLERR_UNFOUND_QUEUE_ID
    • + *
    + */ + public int DdeQueryConvInfo( HCONV hConv, int idTransaction, CONVINFO pConvInfo); + + /** + * Associates an application-defined value with a conversation handle or a + * transaction identifier. This is useful for simplifying the processing of + * asynchronous transactions. An application can use the DdeQueryConvInfo + * function to retrieve this value. + * + * @param hConv A handle to the conversation. + * @param id The transaction identifier to associate with the value + * specified by the hUser parameter. An application should set this + * parameter to QID_SYNC to associate hUser with the conversation identified + * by the hConv parameter. + * @param hUser The value to be associated with the conversation handle. + * @return true If the function succeeds. + * + *

    + * The DdeGetLastError function can be used to get the error code, which can + * be one of the following values:

    + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_NO_ERROR
    • + *
    • DMLERR_UNFOUND_QUEUE_ID
    • + *
    + */ + public boolean DdeSetUserHandle( HCONV hConv, int id, DWORD_PTR hUser); + + /** + * Abandons the specified asynchronous transaction and releases all + * resources associated with the transaction. + * + * @param idInst The application instance identifier obtained by a previous + * call to the DdeInitialize function. + * @param hConv A handle to the conversation in which the transaction was + * initiated. If this parameter is 0L, all transactions are abandoned (that + * is, the idTransaction parameter is ignored). + * @param idTransaction The identifier of the transaction to be abandoned. + * If this parameter is 0L, all active transactions in the specified + * conversation are abandoned. + * @return true if the function succeeds + * + *

    + * The DdeGetLastError function can be used to get the error code, which can + * be one of the following values:

    + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_NO_ERROR
    • + *
    • DMLERR_UNFOUND_QUEUE_ID
    • + *
    + */ + public boolean DdeAbandonTransaction(int idInst, HCONV hConv, int idTransaction); + + /** + * Causes the system to send an XTYP_ADVREQ transaction to the calling + * (server) application's Dynamic Data Exchange (DDE) callback function for + * each client with an active advise loop on the specified topic and item. A + * server application should call this function whenever the data associated + * with the topic name or item name pair changes. + * + * + * @param idInst The application instance identifier obtained by a previous + * call to the DdeInitialize function. + * + * @param hszTopic A handle to a string that specifies the topic name. To + * send notifications for all topics with active advise loops, an + * application can set this parameter to 0L. + * + * @param hszItem A handle to a string that specifies the item name. To send + * notifications for all items with active advise loops, an application can + * set this parameter to 0L. + * + * @return true if the function succeeds + * + *

    + * The DdeGetLastError function can be used to get the error code, which can + * be one of the following values:

    + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_DLL_USAGE
    • + *
    • DMLERR_NO_ERROR
    • + *
    + * + */ + public boolean DdePostAdvise(int idInst, HSZ hszTopic, HSZ hszItem); + + /** + * Enables or disables transactions for a specific conversation or for all + * conversations currently established by the calling application. + * + * @param idInst The application-instance identifier obtained by a previous + * call to the DdeInitialize function. + * @param hConv A handle to the conversation to enable or disable. If this + * parameter is NULL, the function affects all conversations. + * @param wCmd The function code. This parameter can be one of the following + * values. + * + * + * + * + * + * + *
    ValueMeaning
    EC_ENABLEALLEnables all transactions for the specified + * conversation.
    EC_ENABLEONEEnables one transaction for the specified + * conversation.
    EC_DISABLEDisables all blockable transactions for the + * specified conversation. + * + *

    + * A server application can disable the following transactions:

    + *
      + *
    • XTYP_ADVSTART
    • + *
    • XTYP_ADVSTOP
    • + *
    • XTYP_EXECUTE
    • + *
    • XTYP_POKE
    • + *
    • XTYP_REQUEST
    • + *
    + *

    + * A client application can disable the following transactions:

    + *
      + *
    • XTYP_ADVDATA
    • + *
    • XTYP_XACT_COMPLETE
    • + *
    + *
    EC_QUERYWAITINGDetermines whether any transactions are + * in the queue for the specified conversation.
    + * + * @return If the function succeeds, the return value is nonzero. + * + *

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

    + * + *

    + * If the wCmd parameter is EC_QUERYWAITING, and the application transaction + * queue contains one or more unprocessed transactions that are not being + * processed, the return value is TRUE; otherwise, it is FALSE.

    + * + *

    + * The DdeGetLastError function can be used to get the error code, which can + * be one of the following values:

    + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_NO_ERROR
    • + *
    + */ + public boolean DdeEnableCallback(int idInst, HCONV hConv, int wCmd); + + /** + * Impersonates a Dynamic Data Exchange (DDE) client application in a DDE + * client conversation. + * + * @param hConv A handle to the DDE client conversation to be impersonated. + * @return true if the function succeeds + * + *

    To get extended error information call GetLastError.

    + */ + public boolean DdeImpersonateClient(HCONV hConv); + + /** + * Registers or unregisters the service names a Dynamic Data Exchange (DDE) + * server supports. This function causes the system to send XTYP_REGISTER or + * XTYP_UNREGISTER transactions to other running Dynamic Data Exchange + * Management Library (DDEML) client applications. + * + * @param idInst The application instance identifier obtained by a previous + * call to the DdeInitialize function. + * @param hsz1 A handle to the string that specifies the service name the + * server is registering or unregistering. An application that is + * unregistering all of its service names should set this parameter to 0L. + * @param hsz2 Reserved; should be set to 0L. + * @param afCmd The service name options. This parameter can be one of the + * following values. + * + * + * + * + * + * + * + *
    ValueMeaning
    DNS_REGISTERRegisters the error code service + * name.
    DNS_UNREGISTERUnregisters the error code service name. + * If the hsz1 parameter is 0L, all service names registered by the server + * will be unregistered.
    DNS_FILTERONTurns on service name initiation filtering. + * The filter prevents a server from receiving XTYP_CONNECT transactions for + * service names it has not registered. This is the default setting for this + * filter. + *

    + * If a server application does not register any service names, the + * application cannot receive XTYP_WILDCONNECT transactions. + *
    DNS_FILTEROFFTurns off service name initiation + * filtering. If this flag is specified, the server receives an XTYP_CONNECT + * transaction whenever another DDE application calls the DdeConnect + * function, regardless of the service name.
    + * @return If the function succeeds, it returns a nonzero value. That value + * is not a true HDDEDATA value, merely a Boolean indicator of success. The + * function is typed HDDEDATA to allow for possible future expansion of the + * function and a more sophisticated return value. + * + *

    + * If the function fails, the return value is 0L.

    + * + *

    + * The DdeGetLastError function can be used to get the error code, which can + * be one of the following values:

    + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_DLL_USAGE
    • + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_NO_ERROR
    • + *
    + */ + public HDDEDATA DdeNameService(int idInst,HSZ hsz1, HSZ hsz2, int afCmd); + + /** + * Begins a data transaction between a client and a server. Only a Dynamic + * Data Exchange (DDE) client application can call this function, and the + * application can use it only after establishing a conversation with the + * server. + * + * @param pData The beginning of the data the client must pass to the server. + * + *

    Optionally, an application can specify the data handle (HDDEDATA) to + * pass to the server and in that case the cbData parameter should be set + * to -1. This parameter is required only if the wType parameter is + * XTYP_EXECUTE or XTYP_POKE. Otherwise, this parameter should be NULL.

    + * + *

    For the optional usage of this parameter, XTYP_POKE transactions where + * pData is a data handle, the handle must have been created by a previous + * call to the DdeCreateDataHandle function, employing the same data format + * specified in the wFmt parameter.

    + * + * @param cbData The length, in bytes, of the data pointed to by the pData + * parameter, including the terminating NULL, if the data is a string. + * A value of -1 indicates that pData is a data handle that identifies the + * data being sent. + * + * @param hConv A handle to the conversation in which the transaction is to + * take place. + * + * @param hszItem A handle to the data item for which data is being + * exchanged during the transaction. This handle must have been created by + * a previous call to the DdeCreateStringHandle function. This parameter is + * ignored (and should be set to 0L) if the wType parameter is XTYP_EXECUTE. + * + * @param wFmt The standard clipboard format in which the data item is + * being submitted or requested. + * + *

    If the transaction specified by the wType parameter does not pass + * data or is XTYP_EXECUTE, this parameter should be zero.

    + * + *

    If the transaction specified by the wType parameter references + * non-execute DDE data ( XTYP_POKE, XTYP_ADVSTART, XTYP_ADVSTOP, XTYP_REQUEST), + * the wFmt value must be either a valid predefined (CF_) DDE format or a + * valid registered clipboard format.

    + * + * @param wType The transaction type. This parameter can be one of the + * following values. + * + * + * + * + * + * + * + * + *
    ValueMeaning
    XTYP_ADVSTARTBegins an advise loop. Any number of + * distinct advise loops can exist within a conversation. An application can + * alter the advise loop type by combining the XTYP_ADVSTART transaction + * type with one or more of the following flags: + *
    + *
    XTYPF_NODATA.
    Instructs the server to notify the client of + * any data changes without actually sending the data. This flag gives the + * client the option of ignoring the notification or requesting the changed + * data from the server.
    + *
    XTYPF_ACKREQ.
    Instructs the server to wait until the client + * acknowledges that it received the previous data item before sending the + * next data item. This flag prevents a fast server from sending data faster + * than the client can process it.
    + *
    + *
    XTYP_ADVSTOPEnds an advise loop.
    XTYP_EXECUTEBegins an execute transaction.
    XTYP_POKEBegins a poke transaction.
    XTYP_REQUESTBegins a request transaction.
    + * + * @param dwTimeout The maximum amount of time, in milliseconds, that the + * client will wait for a response from the server application in a + * synchronous transaction. This parameter should be TIMEOUT_ASYNC for + * asynchronous transactions. + * + * @param pdwResult A pointer to a variable that receives the result of the + * transaction. An application that does not check the result can use NULL + * for this value. For synchronous transactions, the low-order word of this + * variable contains any applicable DDE_ flags resulting from the + * transaction. This provides support for applications dependent on + * DDE_APPSTATUS bits. It is, however, recommended that applications no + * longer use these bits because they may not be supported in future + * versions of the Dynamic Data Exchange Management Library (DDEML). + * For asynchronous transactions, this variable is filled with a unique + * transaction identifier for use with the DdeAbandonTransaction function + * and the XTYP_XACT_COMPLETE transaction. + * + * @return If the function succeeds, the return value is a data handle that + * identifies the data for successful synchronous transactions in which the + * client expects data from the server. The return value is nonzero for + * successful asynchronous transactions and for synchronous transactions + * in which the client does not expect data. The return value is zero + * for all unsuccessful transactions. + * + *

    The DdeGetLastError function can be used to get the error code, + * which can be one of the following values:

    + * + *
      + *
    • DMLERR_ADVACKTIMEOUT
    • + *
    • DMLERR_BUSY
    • + *
    • DMLERR_DATAACKTIMEOUT
    • + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_EXECACKTIMEOUT
    • + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_MEMORY_ERROR
    • + *
    • DMLERR_NO_CONV_ESTABLISHED
    • + *
    • DMLERR_NO_ERROR
    • + *
    • DMLERR_NOTPROCESSED
    • + *
    • DMLERR_POKEACKTIMEOUT
    • + *
    • DMLERR_POSTMSG_FAILED
    • + *
    • DMLERR_REENTRANCY
    • + *
    • DMLERR_SERVER_DIED
    • + *
    • DMLERR_UNADVACKTIMEOUT
    • + *
    + */ + public HDDEDATA DdeClientTransaction( + Pointer pData, + int cbData, + HCONV hConv, + HSZ hszItem, + int wFmt, + int wType, + int dwTimeout, + WinDef.DWORDByReference pdwResult); + + /** + * Creates a Dynamic Data Exchange (DDE) object and fills the object with + * data from the specified buffer. A DDE application uses this function + * during transactions that involve passing data to the partner application. + * + * @param idInst The application instance identifier obtained by a previous + * call to the DdeInitialize function. + * + * @param pSrc The data to be copied to the DDE object. If this parameter + * is NULL, no data is copied to the object. + * + * @param cb The amount of memory, in bytes, to copy from the buffer pointed + * to by pSrc. (include the terminating NULL, if the data is a string). + * If this parameter is zero, the pSrc parameter is ignored. + * + * @param cbOff An offset, in bytes, from the beginning of the buffer + * pointed to by the pSrc parameter. The data beginning at this offset is + * copied from the buffer to the DDE object. + * + * @param hszItem A handle to the string that specifies the data item + * corresponding to the DDE object. This handle must have been created by a + * previous call to the DdeCreateStringHandle function. If the data handle + * is to be used in an XTYP_EXECUTE transaction, this parameter must be 0L. + * + * @param wFmt The standard clipboard format of the data. + * + * @param afCmd The creation flags. This parameter can be HDATA_APPOWNED, + * which specifies that the server application calling the + * DdeCreateDataHandle function owns the data handle this function creates. + * This flag enables the application to share the data handle with other + * DDEML applications rather than creating a separate handle to pass to each + * application. If this flag is specified, the application must eventually + * free the shared memory object associated with the handle by using the + * DdeFreeDataHandle function. If this flag is not specified, the handle + * becomes invalid in the application that created the handle after the + * data handle is returned by the application's DDE callback function or + * is used as a parameter in another DDEML function. + * + * @return If the function succeeds, the return value is a data handle. + * + *

    If the function fails, the return value is 0L.

    + * + *

    The DdeGetLastError function can be used to get the error code, + * which can be one of the following values:

    + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_MEMORY_ERROR
    • + *
    • DMLERR_NO_ERROR
    • + *
    + */ + public HDDEDATA DdeCreateDataHandle( + int idInst, + Pointer pSrc, + int cb, + int cbOff, + HSZ hszItem, + int wFmt, + int afCmd); + + /** + * Adds data to the specified Dynamic Data Exchange (DDE) object. An + * application can add data starting at any offset from the beginning of + * the object. If new data overlaps data already in the object, + * the new data overwrites the old data in the bytes where the overlap + * occurs. The contents of locations in the object that have not been + * written to are undefined. + * + * @param hData A handle to the DDE object that receives additional data. + * + * @param pSrc The data to be added to the DDE object. + * + * @param cb The length, in bytes, of the data to be added to the DDE + * object, including the terminating NULL, if the data is a string. + * + * @param cbOff An offset, in bytes, from the beginning of the DDE object. + * The additional data is copied to the object beginning at this offset. + * + * @return If the function succeeds, the return value is a new handle to + * the DDE object. The new handle is used in all references to the object. + * + *

    If the function fails, the return value is zero.

    + * + *

    The DdeGetLastError function can be used to get the error code, which + * can be one of the following values:

    + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_MEMORY_ERROR
    • + *
    • DMLERR_NO_ERROR
    • + *
    + */ + public HDDEDATA DdeAddData(HDDEDATA hData, Pointer pSrc, int cb, int cbOff); + + /** + * Copies data from the specified Dynamic Data Exchange (DDE) object to + * the specified local buffer. + * + * @param hData A handle to the DDE object that contains the data to copy. + * + * @param pDst A pointer to the buffer that receives the data. If this + * parameter is NULL, the DdeGetData function returns the amount of data, + * in bytes, that would be copied to the buffer. + * + * @param cbMax The maximum amount of data, in bytes, to copy to the buffer + * pointed to by the pDst parameter. Typically, this parameter specifies + * the length of the buffer pointed to by pDst. + * + * @param cbOff An offset within the DDE object. Data is copied from the + * object beginning at this offset. + * + * @return If the pDst parameter points to a buffer, the return value is + * the size, in bytes, of the memory object associated with the data handle + * or the size specified in the cbMax parameter, whichever is lower. + * + *

    If the pDst parameter is NULL, the return value is the size, in bytes, + * of the memory object associated with the data handle.

    + * + *

    The DdeGetLastError function can be used to get the error code, which + * can be one of the following values:

    + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_NO_ERROR
    • + *
    + */ + public int DdeGetData(HDDEDATA hData, Pointer pDst, int cbMax, int cbOff); + + /** + * Provides access to the data in the specified Dynamic Data Exchange (DDE) object. + * An application must call the DdeUnaccessData function when it has + * finished accessing the data in the object. + * + * @param hData A handle to the DDE object to be accessed. + * + * @param pcbDataSize A pointer to a variable that receives the size, in + * bytes, of the DDE object identified by the hData parameter. If this + * parameter is NULL, no size information is returned. + * + * @return If the function succeeds, the return value is a pointer to the + * first byte of data in the DDE object. + * + *

    If the function fails, the return value is NULL.

    + * + *

    The DdeGetLastError function can be used to get the error code, which can + * be one of the following values:

    + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_NO_ERROR
    • + *
    + */ + public Pointer DdeAccessData(HDDEDATA hData, WinDef.DWORDByReference pcbDataSize); + + /** + * Unaccesses a Dynamic Data Exchange (DDE) object. An application must call + * this function after it has finished accessing the object. + * + * @param hData A handle to the DDE object. + * + * @return true if the function succeeds + * + *

    The DdeGetLastError function can be used to get the error code, which + * can be one of the following values:

    + * + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_NO_ERROR
    • + *
    + */ + public boolean DdeUnaccessData(HDDEDATA hData); + + /** + * Frees a Dynamic Data Exchange (DDE) object and deletes the data handle + * associated with the object. + * + * @param hData A handle to the DDE object to be freed. This handle must + * have been created by a previous call to the DdeCreateDataHandle function + * or returned by the DdeClientTransaction function. + * + * @return true if freeing succeeded + * + *

    The DdeGetLastError function can be used to get the error code, + * which can be one of the following values:

    + *
      + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_NO_ERROR
    • + *
    + */ + public boolean DdeFreeDataHandle(HDDEDATA hData); + + /** + * + * @param idInst The application instance identifier obtained by a previous + * call to the DdeInitialize function. + * + * @return See {@link Ddeml}.DMLERR_* + */ + public int DdeGetLastError(int idInst); + + /** + * Creates a handle that identifies the specified string. A Dynamic + * Data Exchange (DDE) client or server application can pass the string + * handle as a parameter to other Dynamic Data Exchange Management + * Library (DDEML) functions. + * + * @param idInst The application instance identifier obtained by a previous + * call to the DdeInitialize function. + * + * @param psz The null-terminated string for which a handle is to be created. + * This string can be up to 255 characters. The reason for this limit is that + * DDEML string management functions are implemented using atoms. + * + * @param iCodePage The code page to be used to render the string. This + * value should be either CP_WINANSI (the default code page) or + * CP_WINUNICODE, depending on whether the ANSI or Unicode version of + * DdeInitialize was called by the client application. + * + * @return If the function succeeds, the return value is a string handle. + * + *

    If the function fails, the return value is 0L.

    + * + *

    The DdeGetLastError function can be used to get the error code, which + * can be one of the following values:

    + *
      + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_NO_ERROR
    • + *
    • DMLERR_SYS_ERROR
    • + *
    + */ + public HSZ DdeCreateStringHandle(int idInst, String psz, int iCodePage); + + /** + * Copies text associated with a string handle into a buffer. + * + * @param idInst The application instance identifier obtained by a previous + * call to the DdeInitialize function. + * + * @param hsz A handle to the string to copy. This handle must have been + * created by a previous call to the DdeCreateStringHandle function. + * + * @param psz A pointer to a buffer that receives the string. To obtain the + * length of the string, this parameter should be set to NULL. + * + * @param cchMax The length, in characters, of the buffer pointed to by the + * psz parameter. For the ANSI version of the function, this is the number + * of bytes; for the Unicode version, this is the number of characters. + * If the string is longer than ( cchMax� 1), it will be truncated. If the + * psz parameter is set to NULL, this parameter is ignored. + * + * @param iCodePage The code page used to render the string. This value + * should be either CP_WINANSI or CP_WINUNICODE. + * + * @return If the psz parameter specified a valid pointer, the return value + * is the length, in characters, of the returned text + * (not including the terminating null character). If the psz parameter + * specified a NULL pointer, the return value is the length of the text + * associated with the hsz parameter (not including the terminating null + * character). + * + *

    If an error occurs, the return value is 0L

    + */ + public int DdeQueryString(int idInst, HSZ hsz, Pointer psz, int cchMax, int iCodePage); + + /** + * Frees a string handle in the calling application. + * + * @param idInst The application instance identifier obtained by a previous + * call to the DdeInitialize function. + * + * @param hsz A handle to the string handle to be freed. This handle must + * have been created by a previous call to the DdeCreateStringHandle + * function. + * + * @return true if the function succeeds. + * + */ + public boolean DdeFreeStringHandle(int idInst, HSZ hsz); + + /** + * Increments the usage count associated with the specified handle. This + * function enables an application to save a string handle passed to the + * application's Dynamic Data Exchange (DDE) callback function. Otherwise, a + * string handle passed to the callback function is deleted when the + * callback function returns. This function should also be used to keep a + * copy of a string handle referenced by the CONVINFO structure returned by + * the DdeQueryConvInfo function. + * + * @param idInst The application instance identifier obtained by a previous + * call to the DdeInitialize function. + * @param hsz A handle to the string handle to be saved. + * @return true if the function succeeded + */ + public boolean DdeKeepStringHandle(int idInst, HSZ hsz); +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/DdemlUtil.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/DdemlUtil.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/DdemlUtil.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/DdemlUtil.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,3911 @@ +/* + * 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.Memory; +import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.BaseTSD.DWORD_PTR; +import com.sun.jna.platform.win32.BaseTSD.ULONG_PTR; +import com.sun.jna.platform.win32.Ddeml.CONVCONTEXT; +import com.sun.jna.platform.win32.Ddeml.CONVINFO; +import com.sun.jna.platform.win32.Ddeml.HCONV; +import com.sun.jna.platform.win32.Ddeml.HCONVLIST; +import com.sun.jna.platform.win32.Ddeml.HDDEDATA; +import com.sun.jna.platform.win32.Ddeml.HSZ; +import com.sun.jna.platform.win32.Ddeml.HSZPAIR; +import com.sun.jna.platform.win32.User32Util.MessageLoopThread; +import com.sun.jna.platform.win32.User32Util.MessageLoopThread.Handler; +import com.sun.jna.win32.W32APIOptions; +import java.io.Closeable; +import java.io.IOException; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * DdemlUtil defines helper classes, that help with manageing DDE communications. + */ +public abstract class DdemlUtil { + /** + * StandaloneDdeClient is a convenience class, that wraps a DdeClient and + * a {@link User32Util.MessageLoopThread}. The DdeClient needs a running + * windows message loop, which is supplied by the MessageLoopThread. + */ + public static class StandaloneDdeClient implements IDdeClient, Closeable { + + private final MessageLoopThread messageLoop = new MessageLoopThread(); + private final IDdeClient ddeClient; + private final IDdeClient clientDelegate; + + public StandaloneDdeClient() { + ddeClient = new DdeClient(); + IDdeClient messageLoopHandler = (IDdeClient) Proxy.newProxyInstance(StandaloneDdeClient.class.getClassLoader(), + new Class[]{IDdeClient.class}, + messageLoop.new Handler(ddeClient)); + clientDelegate = (IDdeClient) Proxy.newProxyInstance(StandaloneDdeClient.class.getClassLoader(), + new Class[]{IDdeClient.class}, + new MessageLoopWrapper(messageLoop, messageLoopHandler)); + messageLoop.setDaemon(true); + messageLoop.start(); + } + + public Integer getInstanceIdentitifier() { + return ddeClient.getInstanceIdentitifier(); + } + + public void initialize(int afCmd) throws DdemlException { + clientDelegate.initialize(afCmd); + } + + public Ddeml.HSZ createStringHandle(String value) throws DdemlException { + return clientDelegate.createStringHandle(value); + } + + public void nameService(Ddeml.HSZ name, int afCmd) throws DdemlException { + clientDelegate.nameService(name, afCmd); + } + + public int getLastError() { + return clientDelegate.getLastError(); + } + + public IDdeConnection connect(Ddeml.HSZ service, Ddeml.HSZ topic, Ddeml.CONVCONTEXT convcontext) { + return clientDelegate.connect(service, topic, convcontext); + } + + public String queryString(Ddeml.HSZ value) throws DdemlException { + return clientDelegate.queryString(value); + } + + @Override + public Ddeml.HDDEDATA createDataHandle(Pointer pSrc, int cb, int cbOff, Ddeml.HSZ hszItem, int wFmt, int afCmd) { + return clientDelegate.createDataHandle(pSrc, cb, cbOff, hszItem, wFmt, afCmd); + } + + @Override + public void freeDataHandle(Ddeml.HDDEDATA hData) { + clientDelegate.freeDataHandle(hData); + } + + @Override + public Ddeml.HDDEDATA addData(Ddeml.HDDEDATA hData, Pointer pSrc, int cb, int cbOff) { + return clientDelegate.addData(hData, pSrc, cb, cbOff); + } + + @Override + public int getData(Ddeml.HDDEDATA hData, Pointer pDst, int cbMax, int cbOff) { + return clientDelegate.getData(hData, pDst, cbMax, cbOff); + } + + @Override + public Pointer accessData(Ddeml.HDDEDATA hData, WinDef.DWORDByReference pcbDataSize) { + return clientDelegate.accessData(hData, pcbDataSize); + } + + @Override + public void unaccessData(Ddeml.HDDEDATA hData) { + clientDelegate.unaccessData(hData); + } + + @Override + public void postAdvise(Ddeml.HSZ hszTopic, Ddeml.HSZ hszItem) { + clientDelegate.postAdvise(hszTopic, hszItem); + } + + public void close() throws IOException { + clientDelegate.uninitialize(); + messageLoop.exit(); + } + + @Override + public boolean freeStringHandle(Ddeml.HSZ value) { + return clientDelegate.freeStringHandle(value); + } + + @Override + public boolean keepStringHandle(Ddeml.HSZ value) { + return clientDelegate.keepStringHandle(value); + } + + @Override + public void abandonTransactions() { + clientDelegate.abandonTransactions(); + } + + @Override + public IDdeConnectionList connectList(Ddeml.HSZ service, Ddeml.HSZ topic, IDdeConnectionList existingList, Ddeml.CONVCONTEXT ctx) { + return clientDelegate.connectList(service, topic, existingList, ctx); + } + + @Override + public boolean enableCallback(int wCmd) { + return clientDelegate.enableCallback(wCmd); + } + + @Override + public IDdeConnection wrap(HCONV conv) { + return clientDelegate.wrap(conv); + } + + @Override + public IDdeConnection connect(String service, String topic, Ddeml.CONVCONTEXT convcontext) { + return clientDelegate.connect(service, topic, convcontext); + } + + @Override + public boolean uninitialize() { + return clientDelegate.uninitialize(); + } + + @Override + public void postAdvise(String hszTopic, String hszItem) { + clientDelegate.postAdvise(hszTopic, hszItem); + } + + @Override + public IDdeConnectionList connectList(String service, String topic, IDdeConnectionList existingList, Ddeml.CONVCONTEXT ctx) { + return clientDelegate.connectList(service, topic, existingList, ctx); + } + + @Override + public void nameService(String name, int afCmd) throws DdemlException { + clientDelegate.nameService(name, afCmd); + } + + @Override + public void registerAdvstartHandler(AdvstartHandler handler) { + clientDelegate.registerAdvstartHandler(handler); + } + + @Override + public void unregisterAdvstartHandler(AdvstartHandler handler) { + clientDelegate.unregisterAdvstartHandler(handler); + } + + @Override + public void registerAdvstopHandler(AdvstopHandler handler) { + clientDelegate.registerAdvstopHandler(handler); + } + + @Override + public void unregisterAdvstopHandler(AdvstopHandler handler) { + clientDelegate.unregisterAdvstopHandler(handler); + } + + @Override + public void registerConnectHandler(ConnectHandler handler) { + clientDelegate.registerConnectHandler(handler); + } + + @Override + public void unregisterConnectHandler(ConnectHandler handler) { + clientDelegate.unregisterConnectHandler(handler); + } + + @Override + public void registerAdvReqHandler(AdvreqHandler handler) { + clientDelegate.registerAdvReqHandler(handler); + } + + @Override + public void unregisterAdvReqHandler(AdvreqHandler handler) { + clientDelegate.unregisterAdvReqHandler(handler); + } + + @Override + public void registerRequestHandler(RequestHandler handler) { + clientDelegate.registerRequestHandler(handler); + } + + @Override + public void unregisterRequestHandler(RequestHandler handler) { + clientDelegate.unregisterRequestHandler(handler); + } + + @Override + public void registerWildconnectHandler(WildconnectHandler handler) { + clientDelegate.registerWildconnectHandler(handler); + } + + @Override + public void unregisterWildconnectHandler(WildconnectHandler handler) { + clientDelegate.unregisterWildconnectHandler(handler); + } + + @Override + public void registerAdvdataHandler(AdvdataHandler handler) { + clientDelegate.registerAdvdataHandler(handler); + } + + @Override + public void unregisterAdvdataHandler(AdvdataHandler handler) { + clientDelegate.unregisterAdvdataHandler(handler); + } + + @Override + public void registerExecuteHandler(ExecuteHandler handler) { + clientDelegate.registerExecuteHandler(handler); + } + + @Override + public void unregisterExecuteHandler(ExecuteHandler handler) { + clientDelegate.unregisterExecuteHandler(handler); + } + + @Override + public void registerPokeHandler(PokeHandler handler) { + clientDelegate.registerPokeHandler(handler); + } + + @Override + public void unregisterPokeHandler(PokeHandler handler) { + clientDelegate.unregisterPokeHandler(handler); + } + + @Override + public void registerConnectConfirmHandler(ConnectConfirmHandler handler) { + clientDelegate.registerConnectConfirmHandler(handler); + } + + @Override + public void unregisterConnectConfirmHandler(ConnectConfirmHandler handler) { + clientDelegate.unregisterConnectConfirmHandler(handler); + } + + @Override + public void registerDisconnectHandler(DisconnectHandler handler) { + clientDelegate.registerDisconnectHandler(handler); + } + + @Override + public void unregisterDisconnectHandler(DisconnectHandler handler) { + clientDelegate.unregisterDisconnectHandler(handler); + } + + @Override + public void registerErrorHandler(ErrorHandler handler) { + clientDelegate.registerErrorHandler(handler); + } + + @Override + public void unregisterErrorHandler(ErrorHandler handler) { + clientDelegate.unregisterErrorHandler(handler); + } + + @Override + public void registerRegisterHandler(RegisterHandler handler) { + clientDelegate.registerRegisterHandler(handler); + } + + @Override + public void unregisterRegisterHandler(RegisterHandler handler) { + clientDelegate.unregisterRegisterHandler(handler); + } + + @Override + public void registerXactCompleteHandler(XactCompleteHandler handler) { + clientDelegate.registerXactCompleteHandler(handler); + } + + @Override + public void unregisterXactCompleteHandler(XactCompleteHandler handler) { + clientDelegate.unregisterXactCompleteHandler(handler); + } + + @Override + public void registerUnregisterHandler(UnregisterHandler handler) { + clientDelegate.registerUnregisterHandler(handler); + } + + @Override + public void unregisterUnregisterHandler(UnregisterHandler handler) { + clientDelegate.unregisterUnregisterHandler(handler); + } + + @Override + public void registerMonitorHandler(MonitorHandler handler) { + clientDelegate.registerMonitorHandler(handler); + } + + @Override + public void unregisterMonitorHandler(MonitorHandler handler) { + clientDelegate.unregisterMonitorHandler(handler); + } + } + + private static class MessageLoopWrapper implements InvocationHandler { + private final Object delegate; + private final MessageLoopThread loopThread; + + public MessageLoopWrapper(MessageLoopThread thread, Object delegate) { + this.loopThread = thread; + this.delegate = delegate; + } + + public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable { + try { + Object result = method.invoke(delegate, args); + Class wrapClass = null; + if ( result instanceof IDdeConnection ) { + wrapClass = IDdeConnection.class; + } else if (result instanceof IDdeConnectionList) { + wrapClass = IDdeConnectionList.class; + } else if (result instanceof IDdeClient) { + wrapClass = IDdeClient.class; + } + if(wrapClass != null && method.getReturnType().isAssignableFrom(wrapClass)) { + result = wrap(result, wrapClass); + } + return result; + } catch (InvocationTargetException ex) { + Throwable cause = ex.getCause(); + if (cause instanceof Exception) { + throw (Exception) cause; + } else { + throw ex; + } + } + } + + private V wrap(V delegate, Class clazz) { + V messageLoopHandler = (V) Proxy.newProxyInstance(StandaloneDdeClient.class.getClassLoader(), + new Class[]{clazz}, + loopThread.new Handler(delegate)); + V clientDelegate = (V) Proxy.newProxyInstance(StandaloneDdeClient.class.getClassLoader(), + new Class[]{clazz}, + new MessageLoopWrapper(loopThread, messageLoopHandler)); + return clientDelegate; + } + } + + public static class DdeConnection implements IDdeConnection { + private HCONV conv; + private final IDdeClient client; + + public DdeConnection(IDdeClient client, HCONV conv) { + this.conv = conv; + this.client = client; + } + + public Ddeml.HCONV getConv() { + return conv; + } + + @Override + public void abandonTransaction(int transactionId) { + boolean result = Ddeml.INSTANCE.DdeAbandonTransaction(client.getInstanceIdentitifier(), conv, transactionId); + if(! result) { + throw DdemlException.create(client.getLastError()); + } + } + + public void abandonTransactions() { + boolean result = Ddeml.INSTANCE.DdeAbandonTransaction(client.getInstanceIdentitifier(), conv, 0); + if(! result) { + throw DdemlException.create(client.getLastError()); + } + } + + @Override + public Ddeml.HDDEDATA clientTransaction(Pointer data, int dataLength, Ddeml.HSZ item, int wFmt, int transaction, int timeout, WinDef.DWORDByReference result, DWORD_PTR userHandle) { + if(timeout == Ddeml.TIMEOUT_ASYNC && result == null) { + result = new WinDef.DWORDByReference(); + } + Ddeml.HDDEDATA returnData = Ddeml.INSTANCE.DdeClientTransaction(data, dataLength, conv, item, wFmt, transaction, timeout, result); + if(returnData == null) { + throw DdemlException.create(client.getLastError()); + } + if (userHandle != null) { + if (timeout != Ddeml.TIMEOUT_ASYNC) { + setUserHandle(Ddeml.QID_SYNC, userHandle); + } else { + setUserHandle(result.getValue().intValue(), userHandle); + } + } + return returnData; + } + + public Ddeml.HDDEDATA clientTransaction(Pointer data, int dataLength, String item, int wFmt, int transaction, int timeout, WinDef.DWORDByReference result, DWORD_PTR userHandle) { + HSZ itemHSZ = null; + try { + itemHSZ = client.createStringHandle(item); + return clientTransaction(data, dataLength, itemHSZ, wFmt, transaction, timeout, result, userHandle); + } finally { + client.freeStringHandle(itemHSZ); + } + } + + @Override + public void poke(Pointer data, int dataLength, Ddeml.HSZ item, int wFmt, int timeout, WinDef.DWORDByReference result, DWORD_PTR userHandle) { + clientTransaction(data, dataLength, item, wFmt, Ddeml.XTYP_POKE, timeout, result, userHandle); + } + + public void poke(Pointer data, int dataLength, String item, int wFmt, int timeout, WinDef.DWORDByReference result, DWORD_PTR userHandle) { + HSZ itemHSZ = null; + try { + itemHSZ = client.createStringHandle(item); + poke(data, dataLength, itemHSZ, wFmt, timeout, result, userHandle); + } finally { + client.freeStringHandle(itemHSZ); + } + } + + @Override + public Ddeml.HDDEDATA request(Ddeml.HSZ item, int wFmt, int timeout, WinDef.DWORDByReference result, DWORD_PTR userHandle) { + return clientTransaction(Pointer.NULL, 0, item, wFmt, Ddeml.XTYP_REQUEST, timeout, result, userHandle); + } + + public Ddeml.HDDEDATA request(String item, int wFmt, int timeout, WinDef.DWORDByReference result, DWORD_PTR userHandle) { + HSZ itemHSZ = null; + try { + itemHSZ = client.createStringHandle(item); + return request(itemHSZ, wFmt, timeout, result, userHandle); + } finally { + client.freeStringHandle(itemHSZ); + } + } + + @Override + public void execute(String executeString, int timeout, WinDef.DWORDByReference result, DWORD_PTR userHandle) { + Memory mem = new Memory(executeString.length() * 2 + 2); + mem.setWideString(0, executeString); + clientTransaction(mem, (int) mem.size(), (HSZ) null, 0, Ddeml.XTYP_EXECUTE, timeout, result, userHandle); + } + + @Override + public void advstart(Ddeml.HSZ item, int wFmt, int timeout, WinDef.DWORDByReference result, DWORD_PTR userHandle) { + clientTransaction(Pointer.NULL, 0, item, wFmt, Ddeml.XTYP_ADVSTART, timeout, result, userHandle); + } + + public void advstart(String item, int wFmt, int timeout, WinDef.DWORDByReference result, DWORD_PTR userHandle) { + HSZ itemHSZ = null; + try { + itemHSZ = client.createStringHandle(item); + advstart(itemHSZ, wFmt, timeout, result, userHandle); + } finally { + client.freeStringHandle(itemHSZ); + } + } + + @Override + public void advstop(Ddeml.HSZ item, int wFmt, int timeout, WinDef.DWORDByReference result, DWORD_PTR userHandle) { + clientTransaction(Pointer.NULL, 0, item, wFmt, Ddeml.XTYP_ADVSTOP, timeout, result, userHandle); + } + + public void advstop(String item, int wFmt, int timeout, WinDef.DWORDByReference result, DWORD_PTR userHandle) { + HSZ itemHSZ = null; + try { + itemHSZ = client.createStringHandle(item); + advstop(itemHSZ, wFmt, timeout, result, userHandle); + } finally { + client.freeStringHandle(itemHSZ); + } + } + + public void impersonateClient() { + boolean result = Ddeml.INSTANCE.DdeImpersonateClient(conv); + if (!result) { + throw DdemlException.create(client.getLastError()); + } + } + + public void close() { + boolean result = Ddeml.INSTANCE.DdeDisconnect(conv); + if(! result) { + throw DdemlException.create(client.getLastError()); + } + } + + public void reconnect() { + Ddeml.HCONV newConv = Ddeml.INSTANCE.DdeReconnect(conv); + if(newConv != null) { + conv = newConv; + } else { + throw DdemlException.create(client.getLastError()); + } + } + + public boolean enableCallback(int wCmd) { + boolean result = Ddeml.INSTANCE.DdeEnableCallback(client.getInstanceIdentitifier(), conv, wCmd); + if ((!result) && wCmd == Ddeml.EC_QUERYWAITING) { + throw DdemlException.create(client.getLastError()); + } + return result; + } + + public void setUserHandle(int id, DWORD_PTR hUser) throws DdemlException { + boolean result = Ddeml.INSTANCE.DdeSetUserHandle(conv, id, hUser); + if (!result) { + throw DdemlException.create(client.getLastError()); + } + } + + public CONVINFO queryConvInfo(int idTransaction) throws DdemlException { + CONVINFO convInfo = new Ddeml.CONVINFO(); + convInfo.cb = convInfo.size(); + convInfo.ConvCtxt.cb = convInfo.ConvCtxt.size(); + convInfo.write(); + int result = Ddeml.INSTANCE.DdeQueryConvInfo(conv, idTransaction, convInfo); + if (result == 0) { + throw DdemlException.create(client.getLastError()); + } + return convInfo; + } + + } + + public static class DdeConnectionList implements IDdeConnectionList { + private final IDdeClient client; + private final HCONVLIST convList; + + public DdeConnectionList(IDdeClient client, Ddeml.HCONVLIST convList) { + this.convList = convList; + this.client = client; + } + + @Override + public Ddeml.HCONVLIST getHandle() { + return this.convList; + } + + @Override + public IDdeConnection queryNextServer(IDdeConnection prevConnection) { + Ddeml.HCONV conv = Ddeml.INSTANCE.DdeQueryNextServer( + convList, + prevConnection != null ? prevConnection.getConv() : null); + if(conv != null) { + return new DdeConnection(client, conv); + } else { + return null; + } + } + + @Override + public void close() { + boolean result = Ddeml.INSTANCE.DdeDisconnectList(convList); + if(! result){ + throw DdemlException.create(client.getLastError()); + } + } + } + + public static class DdeClient implements IDdeClient { + private Integer idInst; + private final DdeAdapter ddeAdapter = new DdeAdapter(); + + public Integer getInstanceIdentitifier() { + return idInst; + } + + public void initialize(int afCmd) throws DdemlException { + WinDef.DWORDByReference pidInst = new WinDef.DWORDByReference(); + Integer result = Ddeml.INSTANCE.DdeInitialize(pidInst, ddeAdapter, afCmd, 0); + if(result != Ddeml.DMLERR_NO_ERROR) { + throw DdemlException.create(result); + } + idInst = pidInst.getValue().intValue(); + if(ddeAdapter instanceof DdeAdapter) { + ddeAdapter.setInstanceIdentifier(idInst); + } + } + + public Ddeml.HSZ createStringHandle(String value) throws DdemlException { + if(value == null) { + return null; + } + int codePage; + if(W32APIOptions.DEFAULT_OPTIONS == W32APIOptions.UNICODE_OPTIONS) { + codePage = Ddeml.CP_WINUNICODE; + } else { + codePage = Ddeml.CP_WINANSI; + } + Ddeml.HSZ handle = Ddeml.INSTANCE.DdeCreateStringHandle(idInst, value, codePage); + if(handle == null) { + throw DdemlException.create(getLastError()); + } + return handle; + } + + public void nameService(Ddeml.HSZ name, int afCmd) throws DdemlException { + Ddeml.HDDEDATA handle = Ddeml.INSTANCE.DdeNameService(idInst, name, new Ddeml.HSZ(), afCmd); + if (handle == null) { + throw DdemlException.create(getLastError()); + } + } + + public void nameService(String name, int afCmd) throws DdemlException { + HSZ nameHSZ = null; + try { + nameHSZ = createStringHandle(name); + nameService(nameHSZ, afCmd); + } finally { + freeStringHandle(nameHSZ); + } + } + + public int getLastError() { + return Ddeml.INSTANCE.DdeGetLastError(idInst); + } + + public IDdeConnection connect(Ddeml.HSZ service, Ddeml.HSZ topic, Ddeml.CONVCONTEXT convcontext) { + Ddeml.HCONV hconv = Ddeml.INSTANCE.DdeConnect(idInst, service, topic, convcontext); + if(hconv == null) { + throw DdemlException.create(getLastError()); + } + return new DdeConnection(this, hconv); + } + + public IDdeConnection connect(String service, String topic, Ddeml.CONVCONTEXT convcontext) { + HSZ serviceHSZ = null; + HSZ topicHSZ = null; + try { + serviceHSZ = createStringHandle(service); + topicHSZ = createStringHandle(topic); + return connect(serviceHSZ, topicHSZ, convcontext); + } finally { + freeStringHandle(topicHSZ); + freeStringHandle(serviceHSZ); + } + } + + public String queryString(Ddeml.HSZ value) throws DdemlException { + int codePage; + int byteWidth; + if(W32APIOptions.DEFAULT_OPTIONS == W32APIOptions.UNICODE_OPTIONS) { + codePage = Ddeml.CP_WINUNICODE; + byteWidth = 2; + } else { + codePage = Ddeml.CP_WINANSI; + byteWidth = 1; + } + Memory buffer = new Memory((256 + 1) * byteWidth); + try { + int length = Ddeml.INSTANCE.DdeQueryString(idInst, value, buffer, 256, codePage); + if (W32APIOptions.DEFAULT_OPTIONS == W32APIOptions.UNICODE_OPTIONS) { + return buffer.getWideString(0); + } else { + return buffer.getString(0); + } + } finally { + buffer.valid(); + } + } + + + public Ddeml.HDDEDATA createDataHandle(Pointer pSrc, int cb, int cbOff, Ddeml.HSZ hszItem, int wFmt, int afCmd) { + Ddeml.HDDEDATA returnData = Ddeml.INSTANCE.DdeCreateDataHandle(idInst, pSrc, cb, cbOff, hszItem, wFmt, afCmd); + if(returnData == null) { + throw DdemlException.create(getLastError()); + } + return returnData; + } + + public void freeDataHandle(Ddeml.HDDEDATA hData) { + boolean result = Ddeml.INSTANCE.DdeFreeDataHandle(hData); + if(! result) { + throw DdemlException.create(getLastError()); + } + } + + public Ddeml.HDDEDATA addData(Ddeml.HDDEDATA hData, Pointer pSrc, int cb, int cbOff) { + Ddeml.HDDEDATA newHandle = Ddeml.INSTANCE.DdeAddData(hData, pSrc, cb, cbOff); + if(newHandle == null) { + throw DdemlException.create(getLastError()); + } + return newHandle; + } + + public int getData(Ddeml.HDDEDATA hData, Pointer pDst, int cbMax, int cbOff) { + int result = Ddeml.INSTANCE.DdeGetData(hData, pDst, cbMax, cbOff); + int errorCode = getLastError(); + if(errorCode != Ddeml.DMLERR_NO_ERROR) { + throw DdemlException.create(errorCode); + } + return result; + } + + public Pointer accessData(Ddeml.HDDEDATA hData, WinDef.DWORDByReference pcbDataSize) { + Pointer result = Ddeml.INSTANCE.DdeAccessData(hData, pcbDataSize); + if(result == null) { + throw DdemlException.create(getLastError()); + } + return result; + } + + public void unaccessData(Ddeml.HDDEDATA hData) { + boolean result = Ddeml.INSTANCE.DdeUnaccessData(hData); + if (!result) { + throw DdemlException.create(getLastError()); + } + } + + public void postAdvise(Ddeml.HSZ hszTopic, Ddeml.HSZ hszItem) { + boolean result = Ddeml.INSTANCE.DdePostAdvise(idInst, hszTopic, hszItem); + if (!result) { + throw DdemlException.create(getLastError()); + } + } + + public void postAdvise(String topic, String item) { + HSZ itemHSZ = null; + HSZ topicHSZ = null; + try { + topicHSZ = createStringHandle(topic); + itemHSZ = createStringHandle(item); + postAdvise(topicHSZ, itemHSZ); + } finally { + freeStringHandle(topicHSZ); + freeStringHandle(itemHSZ); + } + } + + public boolean freeStringHandle(Ddeml.HSZ value) { + if(value == null) { + return true; + } + return Ddeml.INSTANCE.DdeFreeStringHandle(idInst, value); + } + + public boolean keepStringHandle(Ddeml.HSZ value) { + return Ddeml.INSTANCE.DdeKeepStringHandle(idInst, value); + } + + public void abandonTransactions() { + boolean result = Ddeml.INSTANCE.DdeAbandonTransaction(idInst, null, 0); + if(! result) { + throw DdemlException.create(getLastError()); + } + } + + public IDdeConnectionList connectList(Ddeml.HSZ service, Ddeml.HSZ topic, IDdeConnectionList existingList, Ddeml.CONVCONTEXT ctx) { + Ddeml.HCONVLIST convlist = Ddeml.INSTANCE.DdeConnectList(idInst, service, topic, existingList != null ? existingList.getHandle() : null, ctx); + if(convlist == null) { + throw DdemlException.create(getLastError()); + } else { + return new DdeConnectionList(this, convlist); + } + } + + public IDdeConnectionList connectList(String service, String topic, IDdeConnectionList existingList, Ddeml.CONVCONTEXT ctx) { + HSZ serviceHSZ = null; + HSZ topicHSZ = null; + try { + serviceHSZ = createStringHandle(service); + topicHSZ = createStringHandle(topic); + return connectList(serviceHSZ, topicHSZ, existingList, ctx); + } finally { + freeStringHandle(topicHSZ); + freeStringHandle(serviceHSZ); + } + } + + public boolean enableCallback(int wCmd) { + boolean result = Ddeml.INSTANCE.DdeEnableCallback(idInst, null, wCmd); + if ((!result) && wCmd != Ddeml.EC_QUERYWAITING) { + int errorCode = getLastError(); + if(errorCode != Ddeml.DMLERR_NO_ERROR) { + throw DdemlException.create(getLastError()); + } + } + return result; + } + + public boolean uninitialize() { + return Ddeml.INSTANCE.DdeUninitialize(idInst); + } + + public void close() { + uninitialize(); + } + + public IDdeConnection wrap(HCONV hconv) { + return new DdeConnection(this, hconv); + } + + + public void unregisterDisconnectHandler(DisconnectHandler handler) { + ddeAdapter.unregisterDisconnectHandler(handler); + } + + public void registerAdvstartHandler(AdvstartHandler handler) { + ddeAdapter.registerAdvstartHandler(handler); + } + + public void unregisterAdvstartHandler(AdvstartHandler handler) { + ddeAdapter.unregisterAdvstartHandler(handler); + } + + public void registerAdvstopHandler(AdvstopHandler handler) { + ddeAdapter.registerAdvstopHandler(handler); + } + + public void unregisterAdvstopHandler(AdvstopHandler handler) { + ddeAdapter.unregisterAdvstopHandler(handler); + } + + public void registerConnectHandler(ConnectHandler handler) { + ddeAdapter.registerConnectHandler(handler); + } + + public void unregisterConnectHandler(ConnectHandler handler) { + ddeAdapter.unregisterConnectHandler(handler); + } + + public void registerAdvReqHandler(AdvreqHandler handler) { + ddeAdapter.registerAdvReqHandler(handler); + } + + public void unregisterAdvReqHandler(AdvreqHandler handler) { + ddeAdapter.unregisterAdvReqHandler(handler); + } + + public void registerRequestHandler(RequestHandler handler) { + ddeAdapter.registerRequestHandler(handler); + } + + public void unregisterRequestHandler(RequestHandler handler) { + ddeAdapter.unregisterRequestHandler(handler); + } + + public void registerWildconnectHandler(WildconnectHandler handler) { + ddeAdapter.registerWildconnectHandler(handler); + } + + public void unregisterWildconnectHandler(WildconnectHandler handler) { + ddeAdapter.unregisterWildconnectHandler(handler); + } + + public void registerAdvdataHandler(AdvdataHandler handler) { + ddeAdapter.registerAdvdataHandler(handler); + } + + public void unregisterAdvdataHandler(AdvdataHandler handler) { + ddeAdapter.unregisterAdvdataHandler(handler); + } + + public void registerExecuteHandler(ExecuteHandler handler) { + ddeAdapter.registerExecuteHandler(handler); + } + + public void unregisterExecuteHandler(ExecuteHandler handler) { + ddeAdapter.unregisterExecuteHandler(handler); + } + + public void registerPokeHandler(PokeHandler handler) { + ddeAdapter.registerPokeHandler(handler); + } + + public void unregisterPokeHandler(PokeHandler handler) { + ddeAdapter.unregisterPokeHandler(handler); + } + + public void registerConnectConfirmHandler(ConnectConfirmHandler handler) { + ddeAdapter.registerConnectConfirmHandler(handler); + } + + public void unregisterConnectConfirmHandler(ConnectConfirmHandler handler) { + ddeAdapter.unregisterConnectConfirmHandler(handler); + } + + public void registerDisconnectHandler(DisconnectHandler handler) { + ddeAdapter.registerDisconnectHandler(handler); + } + + public void registerErrorHandler(ErrorHandler handler) { + ddeAdapter.registerErrorHandler(handler); + } + + public void unregisterErrorHandler(ErrorHandler handler) { + ddeAdapter.unregisterErrorHandler(handler); + } + + public void registerRegisterHandler(RegisterHandler handler) { + ddeAdapter.registerRegisterHandler(handler); + } + + public void unregisterRegisterHandler(RegisterHandler handler) { + ddeAdapter.unregisterRegisterHandler(handler); + } + + public void registerXactCompleteHandler(XactCompleteHandler handler) { + ddeAdapter.registerXactCompleteHandler(handler); + } + + public void unregisterXactCompleteHandler(XactCompleteHandler handler) { + ddeAdapter.xactCompleteXactCompleteHandler(handler); + } + + public void registerUnregisterHandler(UnregisterHandler handler) { + ddeAdapter.registerUnregisterHandler(handler); + } + + public void unregisterUnregisterHandler(UnregisterHandler handler) { + ddeAdapter.unregisterUnregisterHandler(handler); + } + + public void registerMonitorHandler(MonitorHandler handler) { + ddeAdapter.registerMonitorHandler(handler); + } + + public void unregisterMonitorHandler(MonitorHandler handler) { + ddeAdapter.unregisterMonitorHandler(handler); + } + } + + public interface AdvstartHandler { + /** + * A server callback function should return TRUE to allow an advise loop + * on the specified topic name and item name pair, or FALSE to deny the + * advise loop. If the callback function returns TRUE, any subsequent + * calls to the DdePostAdvise function by the server on the same topic + * name and item name pair causes the system to send XTYP_ADVREQ + * transactions to the server. + * + *

    + * Remarks

    + *

    If a client requests an advise loop on a topic name, item name, + * and data format for an advise loop that is already established, the + * Dynamic Data Exchange Management Library (DDEML) does not create a + * duplicate advise loop but instead alters the advise loop flags + * (XTYPF_ACKREQ and XTYPF_NODATA) to match the latest request.

    + * + *

    + * This transaction is filtered if the server application specified the + * CBF_FAIL_ADVISES flag in the DdeInitialize function.

    + * + * @param transactionType uType - The transaction type. + * @param dataFormat uFmt - The data format requested by the client. + * @param hconv A handle to the conversation. + * @param topic hsz1 - A handle to the topic name. + * @param item hsz2 - A handle to the item name. + * @return true if advise loop can be started + */ + boolean onAdvstart(int transactionType, int dataFormat, HCONV hconv, HSZ topic, HSZ item); + } + + public interface AdvstopHandler { + + /** + * A client uses the XTYP_ADVSTOP transaction to end an advise loop with + * a server. A Dynamic Data Exchange (DDE) server callback function, + * DdeCallback, receives this transaction when a client specifies + * XTYP_ADVSTOP in the DdeClientTransaction function. + * + * @param transactionType uType - The transaction type. + * @param dataFormat uFmt - The data format associated with the advise + * loop being ended. + * @param hconv A handle to the conversation. + * @param topic hsz1 - A handle to the topic name. + * @param item hsz2 - A handle to the item name. + */ + void onAdvstop(int transactionType, int dataFormat, HCONV hconv, HSZ topic, HSZ item); + } + + public interface ConnectHandler { + /** + * A client uses the XTYP_CONNECT transaction to establish a + * conversation. A Dynamic Data Exchange (DDE) server callback function, + * DdeCallback, receives this transaction when a client specifies a + * service name that the server supports (and a topic name that is not + * NULL) in a call to the DdeConnect function. + * + * @param transactionType uType - The transaction type. + * @param topic hsz1 - A handle to the topic name. + * @param service hsz2 - A handle to the service name. + * @param convcontext dwData1 - CONVCONTEXT structure that contains + * context information for the conversation. If the client is not a + * DDEML application, this parameter is NULL. + * @param sameInstance dwData2 - Specifies whether the client is the + * same application instance as the server. + * @return true is connect can continue + */ + boolean onConnect(int transactionType, HSZ topic, HSZ service, CONVCONTEXT convcontext, boolean sameInstance); + } + + public interface AdvreqHandler { + + /** + * The XTYP_ADVREQ transaction informs the server that an advise + * transaction is outstanding on the specified topic name and item name + * pair and that data corresponding to the topic name and item name pair + * has changed. The system sends this transaction to the Dynamic Data + * Exchange (DDE) callback function, DdeCallback, after the server calls + * the DdePostAdvise function. + * + * @param transactionType uType - The transaction type. + * @param dataFormat uFmt - The format in which the data should be + * submitted to the client. + * @param hconv A handle to the conversation. + * @param topic hsz1 - A handle to the topic name. + * @param item hsz2 - A handle to the item name that has changed. + * @param count The count of XTYP_ADVREQ transactions that remain to be + * processed on the same topic, item, and format name set within the + * context of the current call to the DdePostAdvise function. The count + * is zero if the current XTYP_ADVREQ transaction is the last one. A + * server can use this count to determine whether to create an + * HDATA_APPOWNED data handle to the advise data. + * + *

    + * This is set to CADV_LATEACK if the DDEML issued the XTYP_ADVREQ + * transaction because of a late-arriving DDE_ACK message from a client + * being outrun by the server.

    + * + * @return Data for the changed item or NULL if transaction can't be + * completed. + */ + HDDEDATA onAdvreq(int transactionType, int dataFormat, HCONV hconv, HSZ topic, HSZ item, int count); + } + + public interface RequestHandler { + /** + * A client uses the XTYP_REQUEST transaction to request data from a + * server. A Dynamic Data Exchange (DDE) server callback function, + * DdeCallback, receives this transaction when a client specifies + * XTYP_REQUEST in the DdeClientTransaction function. + * + * @param transactionType uType - The transaction type. + * @param dataFormat uFmt - The format in which the data should be + * submitted to the client. + * @param hconv A handle to the conversation. + * @param topic hsz1 - A handle to the topic name. + * @param item hsz2 - A handle to the item name. + * + * @return Data for the changed item or NULL if transaction can't be + * completed. If the server returns NULL, the client will receive a + * DDE_FNOTPROCESSED flag. + */ + HDDEDATA onRequest(int transactionType, int dataFormat, HCONV hconv, HSZ topic, HSZ item); + } + + public interface WildconnectHandler { + + /** + * Enables a client to establish a conversation on each of the server's + * service name and topic name pairs that match the specified service + * name and topic name. A Dynamic Data Exchange (DDE) server callback + * function, DdeCallback, receives this transaction when a client + * specifies a NULL service name, a NULL topic name, or both in a call + * to the DdeConnect or DdeConnectList function. + * + * @param transactionType uType - The transaction type. + * @param topic A handle to the topic name. If this parameter is NULL, + * the client is requesting a conversation on all topic names that the + * server supports. + * @param service A handle to the service name. If this parameter is + * NULL, the client is requesting a conversation on all service names + * that the server supports. + * @param convcontext dwData1 - CONVCONTEXT structure that contains + * context information for the conversation. If the client is not a + * DDEML application, this parameter is NULL. + * @param sameInstance dwData2 - Specifies whether the client is the + * same application instance as the server. + * @return the supported HSZPAIRs (do not include the terminating pair + * needed be the DdeCallback!) + */ + List onWildconnect(int transactionType, HSZ topic, HSZ service, CONVCONTEXT convcontext, boolean sameInstance); + } + + public interface AdvdataHandler { + /** + * Informs the client that the value of the data item has changed. The + * Dynamic Data Exchange (DDE) client callback function, DdeCallback, + * receives this transaction after establishing an advise loop with a + * server. + * + * @param transactionType uType - The transaction type. + * @param dataFormat uFmt - The format atom of the data sent from the + * server. + * @param hconv A handle to the conversation. + * @param topic hsz1 - A handle to the topic name. + * @param item hsz2 - A handle to the item name. + * @param hdata A handle to the data associated with the topic name and + * item name pair. This parameter is NULL if the client specified the + * XTYPF_NODATA flag when it requested the advise loop. + * @return A DDE callback function should return DDE_FACK if it + * processes this transaction, DDE_FBUSY if it is too busy to process + * this transaction, or DDE_FNOTPROCESSED if it rejects this + * transaction. + */ + int onAdvdata(int transactionType, int dataFormat, HCONV hconv, HSZ topic, HSZ item, HDDEDATA hdata); + } + + public interface ConnectConfirmHandler { + + /** + * A Dynamic Data Exchange (DDE) server callback function, DdeCallback, + * receives the XTYP_CONNECT_CONFIRM transaction to confirm that a + * conversation has been established with a client and to provide the + * server with the conversation handle. The system sends this + * transaction as a result of a previous XTYP_CONNECT or + * XTYP_WILDCONNECT transaction. + * + * @param transactionType uType - The transaction type. + * @param hconv A handle to the new conversation. + * @param topic hsz1 - A handle to the topic name. + * @param service hsz2 - A handle to the service name on which the + * conversation has been established. + * @param sameInstance dwData2 - Specifies whether the client is the + * same application instance as the server. + */ + void onConnectConfirm(int transactionType, Ddeml.HCONV hconv, Ddeml.HSZ topic, Ddeml.HSZ service, boolean sameInstance); + } + + public interface DisconnectHandler { + + /** + * An application's Dynamic Data Exchange (DDE) callback function, + * DdeCallback, receives the XTYP_DISCONNECT transaction when the + * application's partner in a conversation uses the DdeDisconnect + * function to terminate the conversation. + * + *

    + * Remarks

    + * + *

    + * This transaction is filtered if the application specified the + * CBF_SKIP_DISCONNECTS flag in the DdeInitialize function.

    + *

    + * The application can obtain the status of the terminated conversation + * by calling the DdeQueryConvInfo function while processing this + * transaction. The conversation handle becomes invalid after the + * callback function returns.

    + *

    + * An application cannot block this transaction type; the CBR_BLOCK + * return code is ignored.

    + * + * @param transactionType uType - The transaction type. + * @param hconv A handle to that the conversation was terminated. + * @param sameInstance dwData2 - Specifies whether the client is the + * same application instance as the server. + */ + void onDisconnect(int transactionType, HCONV hconv, boolean sameInstance); + } + + public interface ErrorHandler { + + /** + * A Dynamic Data Exchange (DDE) callback function, DdeCallback, + * receives the XTYP_ERROR transaction when a critical error occurs. + * + *

    + * Remarks

    + * + *

    + * An application cannot block this transaction type; the CBR_BLOCK + * return code is ignored. The Dynamic Data Exchange Management Library + * (DDEML) attempts to free memory by removing noncritical resources. An + * application that has blocked conversations should unblock them.

    + * + * @param transactionType uType - The transaction type. + * @param hconv A handle to the conversation associated with the error. + * This parameter is NULL if the error is not associated with a + * conversation. + * @param errorCode dwData1 - The error code in the low-order word. + * Currently, only the following error code is supported. + *

    + * Only Ddeml.DMLERR_LOW_MEMRORY is known: Memory is low; advise, poke, + * or execute data may be lost, or the system may fail.

    + */ + void onError(int transactionType, HCONV hconv, int errorCode); + } + + public interface RegisterHandler { + /** + * A Dynamic Data Exchange (DDE) callback function, DdeCallback, receives the XTYP_REGISTER transaction type whenever a Dynamic Data Exchange Management Library (DDEML) server application uses the DdeNameService function to register a service name, or whenever a non-DDEML application that supports the System topic is started. + * + *

    + * Remarks

    + *

    + * This transaction is filtered if the application specified the + * CBF_SKIP_REGISTRATIONS flag in the DdeInitialize function.

    + *

    + * A application cannot block this transaction type; the CBR_BLOCK + * return code is ignored.

    + *

    + * An application should use the hsz1 parameter to add the service name + * to the list of servers available to the user. An application should + * use the hsz2 parameter to identify which application instance has + * started.

    + * + * @param transactionType uType - The transaction type. + * @param baseServiceName hsz1 - A handle to the base service name being + * registered. + * @param instanceSpecificServiceName hsz2 - A handle to the + * instance-specific service name being registered. + */ + void onRegister(int transactionType, HSZ baseServiceName, HSZ instanceSpecificServiceName); + } + + public interface XactCompleteHandler { + /** + * A Dynamic Data Exchange (DDE) client callback function, DdeCallback, + * receives the XTYP_XACT_COMPLETE transaction when an asynchronous + * transaction, initiated by a call to the DdeClientTransaction + * function, has completed. + * + *

    + * Remarks

    + *

    + * An application must not free the data handle obtained during this + * transaction. An application must, however, copy the data associated + * with the data handle if the application must process the data after + * the callback function returns. An application can use the DdeGetData + * function to copy the data.

    + * + * @param transactionType uType - The transaction type. + * @param dataFormat uFmt - The format of the data associated with the + * completed transaction (if applicable) or NULL if no data was + * exchanged during the transaction. + * @param hConv - A handle to the conversation. + * @param topic hsz1 - A handle to the topic name involved in the + * completed transaction. + * @param item hsz2 - A handle to the item name involved in the + * completed transaction. + * @param hdata A handle to the data involved in the completed + * transaction, if applicable. If the transaction was successful but + * involved no data, this parameter is TRUE. This parameter is NULL if + * the transaction was unsuccessful. + * @param transactionIdentifier dwData1 - The transaction identifier of + * the completed transaction. + * @param statusFlag dwData2 - Any applicable DDE_ status flags in the low word. This parameter provides support for applications dependent on DDE_APPSTATUS bits. It is recommended that applications no longer use these bits � they may not be supported in future versions of the DDEML. + */ + void onXactComplete(int transactionType, int dataFormat, HCONV hConv, HSZ topic, HSZ item, HDDEDATA hdata, ULONG_PTR transactionIdentifier, ULONG_PTR statusFlag); + } + + public interface UnregisterHandler { + /** + * A Dynamic Data Exchange (DDE) callback function, DdeCallback, receives the XTYP_REGISTER transaction type whenever a Dynamic Data Exchange Management Library (DDEML) server application uses the DdeNameService function to register a service name, or whenever a non-DDEML application that supports the System topic is started. + * + *

    + * Remarks

    + *

    + * This transaction is filtered if the application specified the + * CBF_SKIP_REGISTRATIONS flag in the DdeInitialize function.

    + *

    + * A application cannot block this transaction type; the CBR_BLOCK + * return code is ignored.

    + *

    + * An application should use the hsz1 parameter to remove the service + * name from the list of servers available to the user. An application + * should use the hsz2 parameter to identify which application instance + * has terminated.

    + * + * @param transactionType uType - The transaction type. + * @param baseServiceName hsz1 - A handle to the base service name being + * registered. + * @param instanceSpecificServiceName hsz2 - A handle to the + * instance-specific service name being registered. + */ + void onUnregister(int transactionType, HSZ baseServiceName, HSZ instanceSpecificServiceName); + } + + public interface ExecuteHandler { + /** + * A client uses the XTYP_EXECUTE transaction to send a command string + * to the server. A Dynamic Data Exchange (DDE) server callback + * function, DdeCallback, receives this transaction when a client + * specifies XTYP_EXECUTE in the DdeClientTransaction function. + * + *

    + * Remarks

    + *

    + * This transaction is filtered if the server application specified the + * CBF_FAIL_EXECUTES flag in the DdeInitialize function.

    + *

    + * Because most client applications expect a server application to + * perform an XTYP_EXECUTE transaction synchronously, a server should + * attempt to perform all processing of the XTYP_EXECUTE transaction + * either from within the DDE callback function or by returning the + * CBR_BLOCK return code. If the hdata parameter is a command that + * instructs the server to terminate, the server should do so after + * processing the XTYP_EXECUTE transaction.

    + * + * @param transactionType uType - The transaction type. + * @param hconv A handle to the conversation. + * @param topic hsz1 - A handle to the topic name. + * @param commandString A handle to the command string. + * @return A server callback function should return DDE_FACK if it + * processes this transaction, DDE_FBUSY if it is too busy to process + * this transaction, or DDE_FNOTPROCESSED if it rejects this + * transaction. + * + */ + int onExecute(int transactionType, Ddeml.HCONV hconv, Ddeml.HSZ topic, Ddeml.HDDEDATA commandString); + } + + public interface PokeHandler { + /** + * A client uses the XTYP_POKE transaction to send unsolicited data to + * the server. A Dynamic Data Exchange (DDE) server callback function, + * DdeCallback, receives this transaction when a client specifies + * XTYP_POKE in the DdeClientTransaction function. + * + * @param transactionType uType - The transaction type. + * @param dataFormat uFmt - The format of the data sent from the server. + * @param hconv A handle to the conversation. + * @param topic hsz1 - A handle to the topic name. + * @param item hsz2 - A handle to the item name. + * @param hdata - A handle to the data that the client is sending to the + * server. + * @return A server callback function should return the DDE_FACK flag if + * it processes this transaction, the DDE_FBUSY flag if it is too busy + * to process this transaction, or the DDE_FNOTPROCESSED flag if it + * rejects this transaction. + * + */ + int onPoke(int transactionType, int dataFormat, HCONV hconv, HSZ topic, HSZ item, HDDEDATA hdata); + } + + public interface MonitorHandler { + + /** + * A Dynamic Data Exchange (DDE) debugger's DDE callback function, + * DdeCallback, receives the XTYP_MONITOR transaction whenever a DDE + * event occurs in the system. To receive this transaction, an + * application must specify the APPCLASS_MONITOR value when it calls the + * DdeInitialize function. + * + * @param transactionType uType - The transaction type. + * @param hdata A handle to a DDE object that contains information about + * the DDE event. The application should use the DdeAccessData function + * to obtain a pointer to the object. + * @param eventCode dwData2 - The DDE event. This parameter can be one + * of the following values: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
    ValueMeaning
    + * MF_CALLBACKS
    + * 0x08000000 + *
    + * The system sent a transaction to a DDE callback function. The DDE + * object contains a MONCBSTRUCT structure that provides information + * about the transaction. + *
    + * MF_CONV
    + * 0x40000000 + *
    + * A DDE conversation was established or terminated. The DDE object + * contains a MONCONVSTRUCT structure that provides information about + * the conversation. + *
    + * MF_ERRORS
    + * 0x10000000 + *
    + * A DDE error occurred. The DDE object contains a MONERRSTRUCT + * structure that provides information about the error. + *
    + * MF_HSZ_INFO
    + * 0x01000000 + *
    + * A DDE application created, freed, or incremented the usage count of a + * string handle, or a string handle was freed as a result of a call to + * the DdeUninitialize function. The DDE object contains a MONHSZSTRUCT + * structure that provides information about the string handle. + *
    + * MF_LINKS
    + * 0x20000000 + *
    + * A DDE application started or stopped an advise loop. The DDE object + * contains a MONLINKSTRUCT structure that provides information about + * the advise loop. + *
    + * MF_POSTMSGS
    + * 0x04000000 + *
    + * The system or an application posted a DDE message. The DDE object + * contains a MONMSGSTRUCT structure that provides information about the + * message. + *
    + * MF_SENDMSGS
    + * 0x02000000 + *
    + * The system or an application sent a DDE message. The DDE object + * contains a MONMSGSTRUCT structure that provides information about the + * message. + *
    + */ + void onMonitor(int transactionType, HDDEDATA hdata, int eventCode); + } + + /** + * DdeAdapter implements DdeCallback and allow dynamic registration for + * mulitple handlers, that can be registered and unregistered at runtime. + * + *
    + *
    AdvstartHandler
    + *
    All registered AdvstartHandler are evaluated. If at least one returns + * true, the whole evaluation is considered true.
    + *
    AdvstopHandler
    + *
    All registered AdvstopHandler are invoked.
    + *
    ConnectHandler
    + *
    All registered ConnectHandler are evaluated. If at least one returns + * true, the whole evaluation is considered true.
    + *
    WildconnectHandler
    + *
    All registered WildconnectHandler are evaluated. The result is the + * union of all HSZPAIRs.
    + *
    ConnectConfirmHandler
    + *
    All registered ConnectConfirmHandler are evaluated.
    + *
    DisconnectHandler
    + *
    All registered DisconnectHandler are evaluated.
    + *
    ErrorHandler
    + *
    All registered ErrorHandler are evaluated.
    + *
    RegisterHandler
    + *
    All registered RegisterHandler are evaluated.
    + *
    XactCompleteHandler
    + *
    All registered XactCompleteHandler are evaluated.
    + *
    UnregisterHandler
    + *
    All registered UnregisterHandlers are evaluated.
    + *
    MonitorHandler
    + *
    All registered AdvstopHandler are invoked.
    + *
    AdvdataHandler
    + *
    The AdvdataHandlers are evaluated in registration order - evaluation + * stops after the first handler not returning Ddeml.FNOTPROCESSED.
    + *
    ExecuteHandler
    + *
    The ExecuteHandler are evaluated in registration order - evaluation + * stops after the first handler not returning Ddeml.FNOTPROCESSED.
    + *
    PokeHandler
    + *
    The PokeHandler are evaluated in registration order - evaluation + * stops after the first handler not returning Ddeml.FNOTPROCESSED.
    + *
    AdvreqHandler
    + *
    The AdvreqHandlers are evaluated in registration order - evaluation + * stops after the first handler returning a non null value.
    + *
    RequestHandler
    + *
    The RequestHandlers are evaluated in registration order - evaluation + * stops after the first handler returning a non null value.
    + *
    + */ + public static class DdeAdapter implements Ddeml.DdeCallback { + + public static class BlockException extends RuntimeException{}; + + private static final Logger LOG = Logger.getLogger(DdeAdapter.class.getName()); + + private int idInst; + + public void setInstanceIdentifier(int idInst) { + this.idInst = idInst; + } + + public WinDef.PVOID ddeCallback(int wType, int wFmt, Ddeml.HCONV hConv, Ddeml.HSZ hsz1, Ddeml.HSZ hsz2, Ddeml.HDDEDATA hData, BaseTSD.ULONG_PTR lData1, BaseTSD.ULONG_PTR lData2) { + boolean booleanResult; + Ddeml.HDDEDATA data; + Ddeml.CONVCONTEXT convcontext; + int intResult; + String transactionTypeName = null; + try { + switch (wType) { + case Ddeml.XTYP_ADVSTART: + booleanResult = onAdvstart(wType, wFmt, hConv, hsz1, hsz2); + return new WinDef.PVOID(Pointer.createConstant(new WinDef.BOOL(booleanResult).intValue())); + case Ddeml.XTYP_CONNECT: + convcontext = null; + if (lData1.toPointer() != null) { + convcontext = new Ddeml.CONVCONTEXT(new Pointer(lData1.longValue())); + } + booleanResult = onConnect(wType, hsz1, hsz2, convcontext, lData2 != null && lData2.intValue() != 0); + return new WinDef.PVOID(Pointer.createConstant(new WinDef.BOOL(booleanResult).intValue())); + case Ddeml.XTYP_ADVREQ: + int count = lData1.intValue() & 0xFFFF; + data = onAdvreq(wType, wFmt, hConv, hsz1, hsz2, count); + if (data == null) { + return new WinDef.PVOID(); + } else { + return new WinDef.PVOID(data.getPointer()); + } + case Ddeml.XTYP_REQUEST: + data = onRequest(wType, wFmt, hConv, hsz1, hsz2); + if (data == null) { + return new WinDef.PVOID(); + } else { + return new WinDef.PVOID(data.getPointer()); + } + case Ddeml.XTYP_WILDCONNECT: + convcontext = null; + if (lData1.toPointer() != null) { + convcontext = new Ddeml.CONVCONTEXT(new Pointer(lData1.longValue())); + } + Ddeml.HSZPAIR[] hszPairs = onWildconnect(wType, hsz1, hsz2, convcontext, lData2 != null && lData2.intValue() != 0); + if (hszPairs == null || hszPairs.length == 0) { + return new WinDef.PVOID(); + } + int size = 0; + for (Ddeml.HSZPAIR hp : hszPairs) { + hp.write(); + size += hp.size(); + } + data = Ddeml.INSTANCE.DdeCreateDataHandle(idInst, + hszPairs[0].getPointer(), + size, + 0, + null, + wFmt, + 0); + return new WinDef.PVOID(data.getPointer()); + case Ddeml.XTYP_ADVDATA: + intResult = onAdvdata(wType, wFmt, hConv, hsz1, hsz2, hData); + return new WinDef.PVOID(Pointer.createConstant(intResult)); + case Ddeml.XTYP_EXECUTE: + intResult = onExecute(wType, hConv, hsz1, hData); + Ddeml.INSTANCE.DdeFreeDataHandle(hData); + return new WinDef.PVOID(Pointer.createConstant(intResult)); + case Ddeml.XTYP_POKE: + intResult = onPoke(wType, wFmt, hConv, hsz1, hsz2, hData); + return new WinDef.PVOID(Pointer.createConstant(intResult)); + case Ddeml.XTYP_ADVSTOP: + onAdvstop(wType, wFmt, hConv, hsz1, hsz2); + break; + case Ddeml.XTYP_CONNECT_CONFIRM: + onConnectConfirm(wType, hConv, hsz1, hsz2, lData2 != null && lData2.intValue() != 0); + break; + case Ddeml.XTYP_DISCONNECT: + onDisconnect(wType, hConv, lData2 != null && lData2.intValue() != 0); + break; + case Ddeml.XTYP_ERROR: + onError(wType, hConv, (int) (lData2.longValue() & 0xFFFF)); + break; + case Ddeml.XTYP_REGISTER: + onRegister(wType, hsz1, hsz2); + break; + case Ddeml.XTYP_XACT_COMPLETE: + onXactComplete(wType, wFmt, hConv, hsz1, hsz2, hData, lData1, lData2); + break; + case Ddeml.XTYP_UNREGISTER: + onUnregister(wType, hsz1, hsz2); + break; + case Ddeml.XTYP_MONITOR: + onMonitor(wType, hData, lData2.intValue()); + break; + default: + LOG.log(Level.FINE, String.format("Not implemented Operation - Transaction type: 0x%X (%s)", wType, transactionTypeName)); + } + } catch (BlockException ex) { + return new WinDef.PVOID(Pointer.createConstant(-1)); + } catch (Throwable ex) { + LOG.log(Level.WARNING, "Exception in DDECallback", ex); + } + return new WinDef.PVOID(); + }; + + private final List advstartHandler = new CopyOnWriteArrayList(); + + public void registerAdvstartHandler(AdvstartHandler handler) { + advstartHandler.add(handler); + } + + public void unregisterAdvstartHandler(AdvstartHandler handler) { + advstartHandler.remove(handler); + } + + private boolean onAdvstart(int transactionType, int dataFormat, Ddeml.HCONV hconv, Ddeml.HSZ topic, Ddeml.HSZ item) { + boolean oneHandlerTrue = false; + for (AdvstartHandler handler : advstartHandler) { + if (handler.onAdvstart(transactionType, dataFormat, hconv, topic, item)) { + oneHandlerTrue = true; + } + } + return oneHandlerTrue; + } + + private final List advstopHandler = new CopyOnWriteArrayList(); + + public void registerAdvstopHandler(AdvstopHandler handler) { + advstopHandler.add(handler); + } + + public void unregisterAdvstopHandler(AdvstopHandler handler) { + advstopHandler.remove(handler); + } + + private void onAdvstop(int transactionType, int dataFormat, Ddeml.HCONV hconv, Ddeml.HSZ topic, Ddeml.HSZ item) { + for (AdvstopHandler handler : advstopHandler) { + handler.onAdvstop(transactionType, dataFormat, hconv, topic, item); + } + } + + private final List connectHandler = new CopyOnWriteArrayList(); + + public void registerConnectHandler(ConnectHandler handler) { + connectHandler.add(handler); + } + + public void unregisterConnectHandler(ConnectHandler handler) { + connectHandler.remove(handler); + } + + private boolean onConnect(int transactionType, Ddeml.HSZ topic, Ddeml.HSZ service, Ddeml.CONVCONTEXT convcontext, boolean sameInstance) { + boolean oneHandlerTrue = false; + for (ConnectHandler handler : connectHandler) { + if (handler.onConnect( transactionType, topic, service, convcontext, sameInstance)) { + oneHandlerTrue = true; + } + } + return oneHandlerTrue; + } + + private final List advReqHandler = new CopyOnWriteArrayList(); + + public void registerAdvReqHandler(AdvreqHandler handler) { + advReqHandler.add(handler); + } + + public void unregisterAdvReqHandler(AdvreqHandler handler) { + advReqHandler.remove(handler); + } + + private Ddeml.HDDEDATA onAdvreq(int transactionType, int dataFormat, Ddeml.HCONV hconv, Ddeml.HSZ topic, Ddeml.HSZ item, int count) { + for (AdvreqHandler handler : advReqHandler) { + HDDEDATA result = handler.onAdvreq(transactionType, dataFormat, hconv, topic, item, count); + if(result != null) { + return result; + } + } + return null; + } + + private final List requestHandler = new CopyOnWriteArrayList(); + + public void registerRequestHandler(RequestHandler handler) { + requestHandler.add(handler); + } + + public void unregisterRequestHandler(RequestHandler handler) { + requestHandler.remove(handler); + } + + private Ddeml.HDDEDATA onRequest(int transactionType, int dataFormat, Ddeml.HCONV hconv, Ddeml.HSZ topic, Ddeml.HSZ item) { + for (RequestHandler handler : requestHandler) { + HDDEDATA result = handler.onRequest(transactionType, dataFormat, hconv, topic, item); + if(result != null) { + return result; + } + } + return null; + } + + private final List wildconnectHandler = new CopyOnWriteArrayList(); + + public void registerWildconnectHandler(WildconnectHandler handler) { + wildconnectHandler.add(handler); + } + + public void unregisterWildconnectHandler(WildconnectHandler handler) { + wildconnectHandler.remove(handler); + } + + private Ddeml.HSZPAIR[] onWildconnect(int transactionType, HSZ topic, HSZ service, CONVCONTEXT convcontext, boolean sameInstance) { + List hszpairs = new ArrayList(1); + for(WildconnectHandler handler: wildconnectHandler) { + hszpairs.addAll(handler.onWildconnect(transactionType, topic, service, convcontext, sameInstance)); + } + return hszpairs.toArray(new HSZPAIR[hszpairs.size()]); + } + + + private final List advdataHandler = new CopyOnWriteArrayList(); + + public void registerAdvdataHandler(AdvdataHandler handler) { + advdataHandler.add(handler); + } + + public void unregisterAdvdataHandler(AdvdataHandler handler) { + advdataHandler.remove(handler); + } + + private int onAdvdata(int transactionType, int dataFormat, HCONV hconv, HSZ topic, HSZ item, HDDEDATA hdata) { + for (AdvdataHandler handler : advdataHandler) { + int result = handler.onAdvdata(transactionType, dataFormat, hconv, topic, item, hdata); + if(result != Ddeml.DDE_FNOTPROCESSED) { + return result; + } + } + return Ddeml.DDE_FNOTPROCESSED; + } + + private final List executeHandler = new CopyOnWriteArrayList(); + + public void registerExecuteHandler(ExecuteHandler handler) { + executeHandler.add(handler); + } + + public void unregisterExecuteHandler(ExecuteHandler handler) { + executeHandler.remove(handler); + } + + private int onExecute(int transactionType, HCONV hconv, HSZ topic, HDDEDATA commandString) { + for (ExecuteHandler handler : executeHandler) { + int result = handler.onExecute(transactionType, hconv, topic, commandString); + if(result != Ddeml.DDE_FNOTPROCESSED) { + return result; + } + } + return Ddeml.DDE_FNOTPROCESSED; + } + + private final List pokeHandler = new CopyOnWriteArrayList(); + + public void registerPokeHandler(PokeHandler handler) { + pokeHandler.add(handler); + } + + public void unregisterPokeHandler(PokeHandler handler) { + pokeHandler.remove(handler); + } + + private int onPoke(int transactionType, int dataFormat, HCONV hconv, HSZ topic, HSZ item, HDDEDATA hdata) { + for (PokeHandler handler : pokeHandler) { + int result = handler.onPoke(transactionType, dataFormat, hconv, topic, item, hdata); + if(result != Ddeml.DDE_FNOTPROCESSED) { + return result; + } + } + return Ddeml.DDE_FNOTPROCESSED; + } + + private final List connectConfirmHandler = new CopyOnWriteArrayList(); + + public void registerConnectConfirmHandler(ConnectConfirmHandler handler) { + connectConfirmHandler.add(handler); + } + + public void unregisterConnectConfirmHandler(ConnectConfirmHandler handler) { + connectConfirmHandler.remove(handler); + } + + private void onConnectConfirm(int transactionType, HCONV hconv, HSZ topic, HSZ service, boolean sameInstance) { + for(ConnectConfirmHandler handler: connectConfirmHandler) { + handler.onConnectConfirm(transactionType, hconv, topic, service, sameInstance); + } + } + + private final List disconnectHandler = new CopyOnWriteArrayList(); + + public void registerDisconnectHandler(DisconnectHandler handler) { + disconnectHandler.add(handler); + } + + public void unregisterDisconnectHandler(DisconnectHandler handler) { + disconnectHandler.remove(handler); + } + + private void onDisconnect(int transactionType, Ddeml.HCONV hconv, boolean sameInstance) { + for(DisconnectHandler handler: disconnectHandler) { + handler.onDisconnect(transactionType, hconv, sameInstance); + } + } + + private final List errorHandler = new CopyOnWriteArrayList(); + + public void registerErrorHandler(ErrorHandler handler) { + errorHandler.add(handler); + } + + public void unregisterErrorHandler(ErrorHandler handler) { + errorHandler.remove(handler); + } + + private void onError(int transactionType, Ddeml.HCONV hconv, int errorCode) { + for(ErrorHandler handler: errorHandler) { + handler.onError(transactionType, hconv, errorCode); + } + } + + private final List registerHandler = new CopyOnWriteArrayList(); + + public void registerRegisterHandler(RegisterHandler handler) { + registerHandler.add(handler); + } + + public void unregisterRegisterHandler(RegisterHandler handler) { + registerHandler.remove(handler); + } + + private void onRegister(int transactionType, Ddeml.HSZ baseServiceName, Ddeml.HSZ instanceSpecificServiceName) { + for(RegisterHandler handler: registerHandler) { + handler.onRegister(transactionType, baseServiceName, instanceSpecificServiceName); + } + } + + private final List xactCompleteHandler = new CopyOnWriteArrayList(); + + public void registerXactCompleteHandler(XactCompleteHandler handler) { + xactCompleteHandler.add(handler); + } + + public void xactCompleteXactCompleteHandler(XactCompleteHandler handler) { + xactCompleteHandler.remove(handler); + } + + private void onXactComplete(int transactionType, int dataFormat, HCONV hConv, HSZ topic, HSZ item, HDDEDATA hdata, ULONG_PTR transactionIdentifier, ULONG_PTR statusFlag) { + for(XactCompleteHandler handler: xactCompleteHandler) { + handler.onXactComplete(transactionType, dataFormat, hConv, topic, item, hdata, transactionIdentifier, statusFlag); + } + } + + private final List unregisterHandler = new CopyOnWriteArrayList(); + + public void registerUnregisterHandler(UnregisterHandler handler) { + unregisterHandler.add(handler); + } + + public void unregisterUnregisterHandler(UnregisterHandler handler) { + unregisterHandler.remove(handler); + } + + private void onUnregister(int transactionType, HSZ baseServiceName, HSZ instanceSpecificServiceName) { + for(UnregisterHandler handler: unregisterHandler) { + handler.onUnregister(transactionType, baseServiceName, instanceSpecificServiceName); + } + } + + private final List monitorHandler = new CopyOnWriteArrayList(); + + public void registerMonitorHandler(MonitorHandler handler) { + monitorHandler.add(handler); + } + + public void unregisterMonitorHandler(MonitorHandler handler) { + monitorHandler.remove(handler); + } + + private void onMonitor(int transactionType, HDDEDATA hdata, int dwData2) { + for(MonitorHandler handler: monitorHandler) { + handler.onMonitor(transactionType, hdata, dwData2); + } + } + } + + /** + * DdemlException wraps error codes reported by the DDEML functions as an + * exception. + */ + public static class DdemlException extends RuntimeException { + private static final Map ERROR_CODE_MAP; + + static { + 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) { + throw new RuntimeException(ex); + } + } + } + ERROR_CODE_MAP = Collections.unmodifiableMap(errorCodeMapBuilder); + } + + private final int errorCode; + + public static DdemlException create(int errorCode) { + String errorName = ERROR_CODE_MAP.get(errorCode); + return new DdemlException(errorCode, String.format("%s (Code: 0x%X)", + errorName != null ? errorName : "", + errorCode)); + } + + public DdemlException(int errorCode, String message) { + super(message); + this.errorCode = errorCode; + } + + public int getErrorCode() { + return errorCode; + } + } + + /** + * The IDdeConnection defines the functions, that work an a concrete + * connection/conversation. + */ + public interface IDdeConnection extends Closeable { + public Ddeml.HCONV getConv(); + + /** + * Run an XTYP_EXECUTE client transaction. + * + * @param executeString The string passed to the server for execution + * @param timeout The maximum amount of time, in milliseconds, that + * the client will wait for a response from the server application in a + * synchronous transaction. This parameter should be TIMEOUT_ASYNC for + * asynchronous transactions. + * @param result A pointer to a variable that receives the result of + * the transaction. An application that does not check the result can + * use NULL for this value. For synchronous transactions, the low-order + * word of this variable contains any applicable DDE_ flags resulting + * from the transaction. This provides support for applications + * dependent on DDE_APPSTATUS bits. It is, however, recommended that + * applications no longer use these bits because they may not be + * supported in future versions of the Dynamic Data Exchange Management + * Library (DDEML). For asynchronous transactions, this variable is + * filled with a unique transaction identifier for use with the + * DdeAbandonTransaction function and the XTYP_XACT_COMPLETE + * transaction. + * @param userHandle data to associate with the transaction + * + *

    + * If an error occurs, a DdemlException is raised with the appropriate + * error code:

    + * + *
      + *
    • DMLERR_BUSY
    • + *
    • DMLERR_NOTPROCESSED
    • + *
    + */ + public void execute(String executeString, int timeout, WinDef.DWORDByReference result, DWORD_PTR userHandle); + + /** + * Run an XTYP_POKE client transaction + * + * @param data The beginning of the data the client must pass to the + * server. + * + *

    + * Optionally, an application can specify the data handle (HDDEDATA) to + * pass to the server and in that case the cbData parameter should be + * set to -1. This parameter is required only if the wType parameter is + * XTYP_EXECUTE or XTYP_POKE. Otherwise, this parameter should be + * NULL.

    + * + *

    + * For the optional usage of this parameter, XTYP_POKE transactions + * where pData is a data handle, the handle must have been created by a + * previous call to the DdeCreateDataHandle function, employing the same + * data format specified in the wFmt parameter.

    + * + * @param dataLength The length, in bytes, of the data pointed to by the + * pData parameter, including the terminating NULL, if the data is a + * string. A value of -1 indicates that pData is a data handle that + * identifies the data being sent. + * + * @param item A handle to the data item for which data is being + * exchanged during the transaction. This handle must have been created + * by a previous call to the DdeCreateStringHandle function. This + * parameter is ignored (and should be set to 0L) if the wType parameter + * is XTYP_EXECUTE. + * + * @param wFmt The standard clipboard format in which the data item is + * being submitted or requested. + * + *

    + * If the transaction specified by the wType parameter does not pass + * data or is XTYP_EXECUTE, this parameter should be zero.

    + * + *

    + * If the transaction specified by the wType parameter references + * non-execute DDE data ( XTYP_POKE, XTYP_ADVSTART, XTYP_ADVSTOP, + * XTYP_REQUEST), the wFmt value must be either a valid predefined (CF_) + * DDE format or a valid registered clipboard format.

    + * + * @param timeout The maximum amount of time, in milliseconds, that + * the client will wait for a response from the server application in a + * synchronous transaction. This parameter should be TIMEOUT_ASYNC for + * asynchronous transactions. + * + * @param userHandle data to associate with the transaction + * + * @param result A pointer to a variable that receives the result of + * the transaction. An application that does not check the result can + * use NULL for this value. For synchronous transactions, the low-order + * word of this variable contains any applicable DDE_ flags resulting + * from the transaction. This provides support for applications + * dependent on DDE_APPSTATUS bits. It is, however, recommended that + * applications no longer use these bits because they may not be + * supported in future versions of the Dynamic Data Exchange Management + * Library (DDEML). For asynchronous transactions, this variable is + * filled with a unique transaction identifier for use with the + * DdeAbandonTransaction function and the XTYP_XACT_COMPLETE + * transaction. + * + *

    + * If an error occurs, a DdemlException is raised with the appropriate + * error code:

    + * + *
      + *
    • DMLERR_BUSY
    • + *
    • DMLERR_NOTPROCESSED
    • + *
    + */ + public void poke(Pointer data, int dataLength, Ddeml.HSZ item, int wFmt, int timeout, WinDef.DWORDByReference result, DWORD_PTR userHandle); + + /** + * Run an XTYP_POKE client transaction + * + * @param data The beginning of the data the client must pass to the + * server. + * + *

    + * Optionally, an application can specify the data handle (HDDEDATA) to + * pass to the server and in that case the cbData parameter should be + * set to -1. This parameter is required only if the wType parameter is + * XTYP_EXECUTE or XTYP_POKE. Otherwise, this parameter should be + * NULL.

    + * + *

    + * For the optional usage of this parameter, XTYP_POKE transactions + * where pData is a data handle, the handle must have been created by a + * previous call to the DdeCreateDataHandle function, employing the same + * data format specified in the wFmt parameter.

    + * + * @param dataLength The length, in bytes, of the data pointed to by the + * pData parameter, including the terminating NULL, if the data is a + * string. A value of -1 indicates that pData is a data handle that + * identifies the data being sent. + * + * @param item The data item for which data is being + * exchanged during the transaction. This handle must have been created + * by a previous call to the DdeCreateStringHandle function. This + * parameter is ignored (and should be set to 0L) if the wType parameter + * is XTYP_EXECUTE. + * + * @param wFmt The standard clipboard format in which the data item is + * being submitted or requested. + * + *

    + * If the transaction specified by the wType parameter does not pass + * data or is XTYP_EXECUTE, this parameter should be zero.

    + * + *

    + * If the transaction specified by the wType parameter references + * non-execute DDE data ( XTYP_POKE, XTYP_ADVSTART, XTYP_ADVSTOP, + * XTYP_REQUEST), the wFmt value must be either a valid predefined (CF_) + * DDE format or a valid registered clipboard format.

    + * + * @param timeout The maximum amount of time, in milliseconds, that + * the client will wait for a response from the server application in a + * synchronous transaction. This parameter should be TIMEOUT_ASYNC for + * asynchronous transactions. + * + * @param userHandle data to associate with the transaction + * + * @param result A pointer to a variable that receives the result of + * the transaction. An application that does not check the result can + * use NULL for this value. For synchronous transactions, the low-order + * word of this variable contains any applicable DDE_ flags resulting + * from the transaction. This provides support for applications + * dependent on DDE_APPSTATUS bits. It is, however, recommended that + * applications no longer use these bits because they may not be + * supported in future versions of the Dynamic Data Exchange Management + * Library (DDEML). For asynchronous transactions, this variable is + * filled with a unique transaction identifier for use with the + * DdeAbandonTransaction function and the XTYP_XACT_COMPLETE + * transaction. + * + *

    + * If an error occurs, a DdemlException is raised with the appropriate + * error code:

    + * + *
      + *
    • DMLERR_BUSY
    • + *
    • DMLERR_NOTPROCESSED
    • + *
    + */ + public void poke(Pointer data, int dataLength, String item, int wFmt, int timeout, WinDef.DWORDByReference result, DWORD_PTR userHandle); + + /** + * Begins a data transaction between a client and a server. Only a + * Dynamic Data Exchange (DDE) client application can call this + * function, and the application can use it only after establishing a + * conversation with the server. + * + * @param item A handle to the data item for which data is being + * exchanged during the transaction. This handle must have been created + * by a previous call to the DdeCreateStringHandle function. This + * parameter is ignored (and should be set to 0L) if the wType parameter + * is XTYP_EXECUTE. + * + * @param wFmt The standard clipboard format in which the data item is + * being submitted or requested. + * + *

    + * If the transaction specified by the wType parameter references + * non-execute DDE data ( XTYP_POKE, XTYP_ADVSTART, XTYP_ADVSTOP, + * XTYP_REQUEST), the wFmt value must be either a valid predefined (CF_) + * DDE format or a valid registered clipboard format.

    + * + * @param timeout The maximum amount of time, in milliseconds, that + * the client will wait for a response from the server application in a + * synchronous transaction. This parameter should be TIMEOUT_ASYNC for + * asynchronous transactions. + * + * @param result A pointer to a variable that receives the result of + * the transaction. An application that does not check the result can + * use NULL for this value. For synchronous transactions, the low-order + * word of this variable contains any applicable DDE_ flags resulting + * from the transaction. This provides support for applications + * dependent on DDE_APPSTATUS bits. It is, however, recommended that + * applications no longer use these bits because they may not be + * supported in future versions of the Dynamic Data Exchange Management + * Library (DDEML). For asynchronous transactions, this variable is + * filled with a unique transaction identifier for use with the + * DdeAbandonTransaction function and the XTYP_XACT_COMPLETE + * transaction. + * + * @param userHandle data to associate with the transaction + * + * @return If the function succeeds, the return value is a data handle + * that identifies the data for successful synchronous transactions in + * which the client expects data from the server. The return value is + * nonzero for successful asynchronous transactions and for synchronous + * transactions in which the client does not expect data. The return + * value is zero for all unsuccessful transactions. + * + *

    + * If an error occurs, a DdemlException is raised with the appropriate + * error code:

    + * + *
      + *
    • DMLERR_NOTPROCESSED
    • + *
    + */ + public Ddeml.HDDEDATA request(Ddeml.HSZ item, int wFmt, int timeout, WinDef.DWORDByReference result, DWORD_PTR userHandle); + + /** + * Begins a data transaction between a client and a server. Only a + * Dynamic Data Exchange (DDE) client application can call this + * function, and the application can use it only after establishing a + * conversation with the server. + * + * @param item The data item for which data is being + * exchanged during the transaction. This handle must have been created + * by a previous call to the DdeCreateStringHandle function. This + * parameter is ignored (and should be set to 0L) if the wType parameter + * is XTYP_EXECUTE. + * + * @param wFmt The standard clipboard format in which the data item is + * being submitted or requested. + * + *

    + * If the transaction specified by the wType parameter references + * non-execute DDE data ( XTYP_POKE, XTYP_ADVSTART, XTYP_ADVSTOP, + * XTYP_REQUEST), the wFmt value must be either a valid predefined (CF_) + * DDE format or a valid registered clipboard format.

    + * + * @param timeout The maximum amount of time, in milliseconds, that + * the client will wait for a response from the server application in a + * synchronous transaction. This parameter should be TIMEOUT_ASYNC for + * asynchronous transactions. + * + * @param result A pointer to a variable that receives the result of + * the transaction. An application that does not check the result can + * use NULL for this value. For synchronous transactions, the low-order + * word of this variable contains any applicable DDE_ flags resulting + * from the transaction. This provides support for applications + * dependent on DDE_APPSTATUS bits. It is, however, recommended that + * applications no longer use these bits because they may not be + * supported in future versions of the Dynamic Data Exchange Management + * Library (DDEML). For asynchronous transactions, this variable is + * filled with a unique transaction identifier for use with the + * DdeAbandonTransaction function and the XTYP_XACT_COMPLETE + * transaction. + * + * @param userHandle data to associate with the transaction + * + * @return If the function succeeds, the return value is a data handle + * that identifies the data for successful synchronous transactions in + * which the client expects data from the server. The return value is + * nonzero for successful asynchronous transactions and for synchronous + * transactions in which the client does not expect data. The return + * value is zero for all unsuccessful transactions. + * + *

    + * If an error occurs, a DdemlException is raised with the appropriate + * error code:

    + * + *
      + *
    • DMLERR_NOTPROCESSED
    • + *
    + */ + public Ddeml.HDDEDATA request(String item, int wFmt, int timeout, WinDef.DWORDByReference result, DWORD_PTR userHandle); + + /** + * Begins a data transaction between a client and a server. Only a + * Dynamic Data Exchange (DDE) client application can call this + * function, and the application can use it only after establishing a + * conversation with the server. + * + * @param data The beginning of the data the client must pass to the + * server. + * + *

    + * Optionally, an application can specify the data handle (HDDEDATA) to + * pass to the server and in that case the cbData parameter should be + * set to -1. This parameter is required only if the wType parameter is + * XTYP_EXECUTE or XTYP_POKE. Otherwise, this parameter should be + * NULL.

    + * + *

    + * For the optional usage of this parameter, XTYP_POKE transactions + * where pData is a data handle, the handle must have been created by a + * previous call to the DdeCreateDataHandle function, employing the same + * data format specified in the wFmt parameter.

    + * + * @param dataLength The length, in bytes, of the data pointed to by the + * pData parameter, including the terminating NULL, if the data is a + * string. A value of -1 indicates that pData is a data handle that + * identifies the data being sent. + * + * @param item A handle to the data item for which data is being + * exchanged during the transaction. This handle must have been created + * by a previous call to the DdeCreateStringHandle function. This + * parameter is ignored (and should be set to 0L) if the wType parameter + * is XTYP_EXECUTE. + * + * @param wFmt The standard clipboard format in which the data item is + * being submitted or requested. + * + *

    + * If the transaction specified by the wType parameter does not pass + * data or is XTYP_EXECUTE, this parameter should be zero.

    + * + *

    + * If the transaction specified by the wType parameter references + * non-execute DDE data ( XTYP_POKE, XTYP_ADVSTART, XTYP_ADVSTOP, + * XTYP_REQUEST), the wFmt value must be either a valid predefined (CF_) + * DDE format or a valid registered clipboard format.

    + * + * @param transaction The transaction type. This parameter can be one of the + * following values. + * + * + * + * + * + * + * + * + *
    ValueMeaning
    XTYP_ADVSTARTBegins an advise loop. Any number of + * distinct advise loops can exist within a conversation. An application + * can alter the advise loop type by combining the XTYP_ADVSTART + * transaction type with one or more of the following flags: + *
    + *
    XTYPF_NODATA.
    Instructs the server to notify the client + * of any data changes without actually sending the data. This flag + * gives the client the option of ignoring the notification or + * requesting the changed data from the server.
    + *
    XTYPF_ACKREQ.
    Instructs the server to wait until the + * client acknowledges that it received the previous data item before + * sending the next data item. This flag prevents a fast server from + * sending data faster than the client can process it.
    + *
    + *
    XTYP_ADVSTOPEnds an advise loop.
    XTYP_EXECUTEBegins an execute transaction.
    XTYP_POKEBegins a poke transaction.
    XTYP_REQUESTBegins a request transaction.
    + * + * @param timeout The maximum amount of time, in milliseconds, that + * the client will wait for a response from the server application in a + * synchronous transaction. This parameter should be TIMEOUT_ASYNC for + * asynchronous transactions. + * + * @param result A pointer to a variable that receives the result of + * the transaction. An application that does not check the result can + * use NULL for this value. For synchronous transactions, the low-order + * word of this variable contains any applicable DDE_ flags resulting + * from the transaction. This provides support for applications + * dependent on DDE_APPSTATUS bits. It is, however, recommended that + * applications no longer use these bits because they may not be + * supported in future versions of the Dynamic Data Exchange Management + * Library (DDEML). For asynchronous transactions, this variable is + * filled with a unique transaction identifier for use with the + * DdeAbandonTransaction function and the XTYP_XACT_COMPLETE + * transaction. + * + * @param userHandle data to associate with the transaction + * + * @return If the function succeeds, the return value is a data handle + * that identifies the data for successful synchronous transactions in + * which the client expects data from the server. The return value is + * nonzero for successful asynchronous transactions and for synchronous + * transactions in which the client does not expect data. The return + * value is zero for all unsuccessful transactions. + * + *

    + * If an error occurs, a DdemlException is raised with the appropriate + * error code:

    + * + *
      + *
    • DMLERR_ADVACKTIMEOUT
    • + *
    • DMLERR_BUSY
    • + *
    • DMLERR_DATAACKTIMEOUT
    • + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_EXECACKTIMEOUT
    • + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_MEMORY_ERROR
    • + *
    • DMLERR_NO_CONV_ESTABLISHED
    • + *
    • DMLERR_NO_ERROR
    • + *
    • DMLERR_NOTPROCESSED
    • + *
    • DMLERR_POKEACKTIMEOUT
    • + *
    • DMLERR_POSTMSG_FAILED
    • + *
    • DMLERR_REENTRANCY
    • + *
    • DMLERR_SERVER_DIED
    • + *
    • DMLERR_UNADVACKTIMEOUT
    • + *
    + */ + public Ddeml.HDDEDATA clientTransaction(Pointer data, int dataLength, Ddeml.HSZ item, int wFmt, int transaction, int timeout, WinDef.DWORDByReference result, DWORD_PTR userHandle); + + /** + * Begins a data transaction between a client and a server. Only a + * Dynamic Data Exchange (DDE) client application can call this + * function, and the application can use it only after establishing a + * conversation with the server. + * + * @param data The beginning of the data the client must pass to the + * server. + * + *

    + * Optionally, an application can specify the data handle (HDDEDATA) to + * pass to the server and in that case the cbData parameter should be + * set to -1. This parameter is required only if the wType parameter is + * XTYP_EXECUTE or XTYP_POKE. Otherwise, this parameter should be + * NULL.

    + * + *

    + * For the optional usage of this parameter, XTYP_POKE transactions + * where pData is a data handle, the handle must have been created by a + * previous call to the DdeCreateDataHandle function, employing the same + * data format specified in the wFmt parameter.

    + * + * @param dataLength The length, in bytes, of the data pointed to by the + * pData parameter, including the terminating NULL, if the data is a + * string. A value of -1 indicates that pData is a data handle that + * identifies the data being sent. + * + * @param item The data item for which data is being + * exchanged during the transaction. This handle must have been created + * by a previous call to the DdeCreateStringHandle function. This + * parameter is ignored (and should be set to 0L) if the wType parameter + * is XTYP_EXECUTE. + * + * @param wFmt The standard clipboard format in which the data item is + * being submitted or requested. + * + *

    + * If the transaction specified by the wType parameter does not pass + * data or is XTYP_EXECUTE, this parameter should be zero.

    + * + *

    + * If the transaction specified by the wType parameter references + * non-execute DDE data ( XTYP_POKE, XTYP_ADVSTART, XTYP_ADVSTOP, + * XTYP_REQUEST), the wFmt value must be either a valid predefined (CF_) + * DDE format or a valid registered clipboard format.

    + * + * @param transaction The transaction type. This parameter can be one of the + * following values. + * + * + * + * + * + * + * + * + *
    ValueMeaning
    XTYP_ADVSTARTBegins an advise loop. Any number of + * distinct advise loops can exist within a conversation. An application + * can alter the advise loop type by combining the XTYP_ADVSTART + * transaction type with one or more of the following flags: + *
    + *
    XTYPF_NODATA.
    Instructs the server to notify the client + * of any data changes without actually sending the data. This flag + * gives the client the option of ignoring the notification or + * requesting the changed data from the server.
    + *
    XTYPF_ACKREQ.
    Instructs the server to wait until the + * client acknowledges that it received the previous data item before + * sending the next data item. This flag prevents a fast server from + * sending data faster than the client can process it.
    + *
    + *
    XTYP_ADVSTOPEnds an advise loop.
    XTYP_EXECUTEBegins an execute transaction.
    XTYP_POKEBegins a poke transaction.
    XTYP_REQUESTBegins a request transaction.
    + * + * @param timeout The maximum amount of time, in milliseconds, that + * the client will wait for a response from the server application in a + * synchronous transaction. This parameter should be TIMEOUT_ASYNC for + * asynchronous transactions. + * + * @param result A pointer to a variable that receives the result of + * the transaction. An application that does not check the result can + * use NULL for this value. For synchronous transactions, the low-order + * word of this variable contains any applicable DDE_ flags resulting + * from the transaction. This provides support for applications + * dependent on DDE_APPSTATUS bits. It is, however, recommended that + * applications no longer use these bits because they may not be + * supported in future versions of the Dynamic Data Exchange Management + * Library (DDEML). For asynchronous transactions, this variable is + * filled with a unique transaction identifier for use with the + * DdeAbandonTransaction function and the XTYP_XACT_COMPLETE + * transaction. + * + * @param userHandle data to associate with the transaction + * + * @return If the function succeeds, the return value is a data handle + * that identifies the data for successful synchronous transactions in + * which the client expects data from the server. The return value is + * nonzero for successful asynchronous transactions and for synchronous + * transactions in which the client does not expect data. The return + * value is zero for all unsuccessful transactions. + * + *

    + * If an error occurs, a DdemlException is raised with the appropriate + * error code:

    + * + *
      + *
    • DMLERR_ADVACKTIMEOUT
    • + *
    • DMLERR_BUSY
    • + *
    • DMLERR_DATAACKTIMEOUT
    • + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_EXECACKTIMEOUT
    • + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_MEMORY_ERROR
    • + *
    • DMLERR_NO_CONV_ESTABLISHED
    • + *
    • DMLERR_NO_ERROR
    • + *
    • DMLERR_NOTPROCESSED
    • + *
    • DMLERR_POKEACKTIMEOUT
    • + *
    • DMLERR_POSTMSG_FAILED
    • + *
    • DMLERR_REENTRANCY
    • + *
    • DMLERR_SERVER_DIED
    • + *
    • DMLERR_UNADVACKTIMEOUT
    • + *
    + */ + public Ddeml.HDDEDATA clientTransaction(Pointer data, int dataLength, String item, int wFmt, int transaction, int timeout, WinDef.DWORDByReference result, DWORD_PTR userHandle); + + /** + * Begins a data transaction between a client and a server. Only a + * Dynamic Data Exchange (DDE) client application can call this + * function, and the application can use it only after establishing a + * conversation with the server. + * + * @param item A handle to the data item for which data is being + * exchanged during the transaction. This handle must have been created + * by a previous call to the DdeCreateStringHandle function. This + * parameter is ignored (and should be set to 0L) if the wType parameter + * is XTYP_EXECUTE. + * + * @param wFmt The standard clipboard format in which the data item is + * being submitted or requested. + * + * @param timeout The maximum amount of time, in milliseconds, that + * the client will wait for a response from the server application in a + * synchronous transaction. This parameter should be TIMEOUT_ASYNC for + * asynchronous transactions. + * + * @param result A pointer to a variable that receives the result of + * the transaction. An application that does not check the result can + * use NULL for this value. For synchronous transactions, the low-order + * word of this variable contains any applicable DDE_ flags resulting + * from the transaction. This provides support for applications + * dependent on DDE_APPSTATUS bits. It is, however, recommended that + * applications no longer use these bits because they may not be + * supported in future versions of the Dynamic Data Exchange Management + * Library (DDEML). For asynchronous transactions, this variable is + * filled with a unique transaction identifier for use with the + * DdeAbandonTransaction function and the XTYP_XACT_COMPLETE + * transaction. + * + * @param userHandle data to associate with the transaction + * + *

    + * If an error occurs, a DdemlException is raised with the appropriate + * error code:

    + * + *
      + *
    • DMLERR_NOTPROCESSED
    • + *
    + */ + public void advstart(Ddeml.HSZ item, int wFmt, int timeout, WinDef.DWORDByReference result, DWORD_PTR userHandle); + + /** + * Begins a data transaction between a client and a server. Only a + * Dynamic Data Exchange (DDE) client application can call this + * function, and the application can use it only after establishing a + * conversation with the server. + * + * @param item The data item for which data is being exchanged during + * the transaction. This handle must have been created by a previous + * call to the DdeCreateStringHandle function. This parameter is ignored + * (and should be set to 0L) if the wType parameter is XTYP_EXECUTE. + * + * @param wFmt The standard clipboard format in which the data item is + * being submitted or requested. + * + * @param timeout The maximum amount of time, in milliseconds, that + * the client will wait for a response from the server application in a + * synchronous transaction. This parameter should be TIMEOUT_ASYNC for + * asynchronous transactions. + * + * @param result A pointer to a variable that receives the result of + * the transaction. An application that does not check the result can + * use NULL for this value. For synchronous transactions, the low-order + * word of this variable contains any applicable DDE_ flags resulting + * from the transaction. This provides support for applications + * dependent on DDE_APPSTATUS bits. It is, however, recommended that + * applications no longer use these bits because they may not be + * supported in future versions of the Dynamic Data Exchange Management + * Library (DDEML). For asynchronous transactions, this variable is + * filled with a unique transaction identifier for use with the + * DdeAbandonTransaction function and the XTYP_XACT_COMPLETE + * transaction. + * + * @param userHandle data to associate with the transaction + * + *

    + * If an error occurs, a DdemlException is raised with the appropriate + * error code:

    + * + *
      + *
    • DMLERR_NOTPROCESSED
    • + *
    + */ + public void advstart(String item, int wFmt, int timeout, WinDef.DWORDByReference result, DWORD_PTR userHandle); + + /** + * A client uses the XTYP_ADVSTOP transaction to end an advise loop with + * a server. A Dynamic Data Exchange (DDE) server callback function, + * DdeCallback, receives this transaction when a client specifies + * XTYP_ADVSTOP in the DdeClientTransaction function. + * + * @param item A handle to the data item for which data is being + * exchanged during the transaction. This handle must have been created + * by a previous call to the DdeCreateStringHandle function. This + * parameter is ignored (and should be set to 0L) if the wType parameter + * is XTYP_EXECUTE. + * + * @param wFmt The standard clipboard format in which the data item is + * being submitted or requested. + * + * @param timeout The maximum amount of time, in milliseconds, that + * the client will wait for a response from the server application in a + * synchronous transaction. This parameter should be TIMEOUT_ASYNC for + * asynchronous transactions. + * + * @param result A pointer to a variable that receives the result of + * the transaction. An application that does not check the result can + * use NULL for this value. For synchronous transactions, the low-order + * word of this variable contains any applicable DDE_ flags resulting + * from the transaction. This provides support for applications + * dependent on DDE_APPSTATUS bits. It is, however, recommended that + * applications no longer use these bits because they may not be + * supported in future versions of the Dynamic Data Exchange Management + * Library (DDEML). For asynchronous transactions, this variable is + * filled with a unique transaction identifier for use with the + * DdeAbandonTransaction function and the XTYP_XACT_COMPLETE + * transaction. + * + * @param userHandle data to associate with the transaction + * + *

    + * If an error occurs, a DdemlException is raised with the appropriate + * error code:

    + * + *
      + *
    • DMLERR_NOTPROCESSED
    • + *
    + */ + public void advstop(Ddeml.HSZ item, int wFmt, int timeout, WinDef.DWORDByReference result, DWORD_PTR userHandle); + + /** + * A client uses the XTYP_ADVSTOP transaction to end an advise loop with + * a server. A Dynamic Data Exchange (DDE) server callback function, + * DdeCallback, receives this transaction when a client specifies + * XTYP_ADVSTOP in the DdeClientTransaction function. + * + * @param item The data item for which data is being + * exchanged during the transaction. This handle must have been created + * by a previous call to the DdeCreateStringHandle function. This + * parameter is ignored (and should be set to 0L) if the wType parameter + * is XTYP_EXECUTE. + * + * @param wFmt The standard clipboard format in which the data item is + * being submitted or requested. + * + * @param timeout The maximum amount of time, in milliseconds, that + * the client will wait for a response from the server application in a + * synchronous transaction. This parameter should be TIMEOUT_ASYNC for + * asynchronous transactions. + * + * @param result A pointer to a variable that receives the result of + * the transaction. An application that does not check the result can + * use NULL for this value. For synchronous transactions, the low-order + * word of this variable contains any applicable DDE_ flags resulting + * from the transaction. This provides support for applications + * dependent on DDE_APPSTATUS bits. It is, however, recommended that + * applications no longer use these bits because they may not be + * supported in future versions of the Dynamic Data Exchange Management + * Library (DDEML). For asynchronous transactions, this variable is + * filled with a unique transaction identifier for use with the + * DdeAbandonTransaction function and the XTYP_XACT_COMPLETE + * transaction. + * + * @param userHandle data to associate with the transaction + * + *

    + * If an error occurs, a DdemlException is raised with the appropriate + * error code:

    + * + *
      + *
    • DMLERR_NOTPROCESSED
    • + *
    + */ + public void advstop(String item, int wFmt, int timeout, WinDef.DWORDByReference result, DWORD_PTR userHandle); + + /** + * Abandons the specified asynchronous transaction and releases all + * resources associated with the transaction. + * + * @param transactionId The identifier of the transaction to be + * abandoned. If this parameter is 0L, all active transactions in the + * specified conversation are abandoned. + * + *

    + * If the method fails a DdeException will be raised with the + * corresponding errorCode:

    + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_NO_ERROR
    • + *
    • DMLERR_UNFOUND_QUEUE_ID
    • + *
    + */ + public void abandonTransaction(int transactionId); + + /** + * Abandons all transactions of this conversation and releases all + * resources associated with the transaction. + * + *

    + * If the method fails a DdeException will be raised with the + * corresponding errorCode:

    + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_NO_ERROR
    • + *
    • DMLERR_UNFOUND_QUEUE_ID
    • + *
    + */ + public void abandonTransactions(); + + /** + * Impersonates a Dynamic Data Exchange (DDE) client application in a + * DDE client conversation. + */ + public void impersonateClient(); + + /** + * Terminates a conversation started by either the DdeConnect or + * DdeConnectList function and invalidates the specified conversation + * handle. + * + *

    Note: This wraps the DdeDisconnect function and aligns the name + * with the Closable-wording.

    + * + *

    + * If the method fails a DdeException will be raised with the + * corresponding errorCode:

    + * + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_NO_CONV_ESTABLISHED
    • + *
    • DMLERR_NO_ERROR
    • + *
    + */ + public void close(); + + /** + * Enables a client Dynamic Data Exchange Management Library (DDEML) + * application to attempt to reestablish a conversation with a service + * that has terminated a conversation with the client. When the + * conversation is reestablished, the Dynamic Data Exchange Management + * Library (DDEML) attempts to reestablish any preexisting advise loops. + * + *

    + * If the method fails a DdeException will be raised with the + * corresponding errorCode:

    + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_NO_CONV_ESTABLISHED
    • + *
    • DMLERR_NO_ERROR
    • + *
    + */ + public void reconnect(); + + /** + * Enables or disables transactions for a specific conversation or for + * all conversations currently established by the calling application. + * + * @param wCmd The function code. This parameter can be one of the + * following values. + * + * + * + * + * + * + *
    ValueMeaning
    EC_ENABLEALLEnables all transactions for the + * specified conversation.
    EC_ENABLEONEEnables one transaction for the + * specified conversation.
    EC_DISABLEDisables all blockable transactions for + * the specified conversation. + * + *

    + * A server application can disable the following transactions:

    + *
      + *
    • XTYP_ADVSTART
    • + *
    • XTYP_ADVSTOP
    • + *
    • XTYP_EXECUTE
    • + *
    • XTYP_POKE
    • + *
    • XTYP_REQUEST
    • + *
    + *

    + * A client application can disable the following transactions:

    + *
      + *
    • XTYP_ADVDATA
    • + *
    • XTYP_XACT_COMPLETE
    • + *
    + *
    EC_QUERYWAITINGDetermines whether any transactions + * are in the queue for the specified conversation.
    + * + * @return If the function succeeds, the return value is nonzero. + * + *

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

    + * + *

    + * If the wCmd parameter is EC_QUERYWAITING, and the application + * transaction queue contains one or more unprocessed transactions that + * are not being processed, the return value is TRUE; otherwise, it is + * FALSE.

    + * + *

    + * If the method fails a DdeException will be raised with the + * corresponding errorCode:

    + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_NO_ERROR
    • + *
    + */ + public boolean enableCallback(int wCmd); + + /** + * Associates an application-defined value with a conversation handle or + * a transaction identifier. This is useful for simplifying the + * processing of asynchronous transactions. An application can use the + * DdeQueryConvInfo function to retrieve this value. + * + * @param id The transaction identifier to associate with the value + * specified by the hUser parameter. An application should set this + * parameter to QID_SYNC to associate hUser with the conversation + * identified by the hConv parameter. + * @param hUser The value to be associated with the conversation handle. + * + *

    + * If the method fails a DdeException will be raised with the + * corresponding errorCode:

    + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_NO_ERROR
    • + *
    • DMLERR_UNFOUND_QUEUE_ID
    • + *
    + */ + public void setUserHandle(int id, DWORD_PTR hUser) throws DdemlException; + + /** + * Retrieves information about a Dynamic Data Exchange (DDE) transaction + * and about the conversation in which the transaction takes place. + * + * @param idTransaction The transaction. For asynchronous transactions, + * this parameter should be a transaction identifier returned by the + * DdeClientTransaction function. For synchronous transactions, this + * parameter should be QID_SYNC. + * @return The CONVINFO structure + * + *

    + * If the method fails a DdeException will be raised with the + * corresponding errorCode:

    + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_NO_CONV_ESTABLISHED
    • + *
    • DMLERR_NO_ERROR
    • + *
    • DMLERR_UNFOUND_QUEUE_ID
    • + *
    + */ + public CONVINFO queryConvInfo(int idTransaction) throws DdemlException; + } + + /** + * The IDdeClient defines functions that wrap a ddeml instance. and are + * not tied to conversation. + */ + public interface IDdeClient extends Closeable { + public Integer getInstanceIdentitifier(); + /** + * Registers an application with the Dynamic Data Exchange Management + * Library (DDEML). An application must call this function before + * calling any other Dynamic Data Exchange Management Library (DDEML) + * function. + * + * @param afCmd A set of APPCMD_, CBF_, and MF_ flags. The APPCMD_ flags + * provide special instructions to DdeInitialize. The CBF_ flags specify + * filters that prevent specific types of transactions from reaching the + * callback function. The MF_ flags specify the types of DDE activity + * that a DDE monitoring application monitors. Using these flags + * enhances the performance of a DDE application by eliminating + * unnecessary calls to the callback function. + * + *

    + * This parameter can be one or more of the following values.

    + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
    ValueMeaning
    + *
    APPCLASS_MONITOR
    + *
    0x00000001L
    + *
    + *
    + *

    + * Makes it possible for the application to monitor DDE activity in the + * system. This flag is for use by DDE monitoring applications. The + * application specifies the types of DDE activity to monitor by + * combining one or more monitor flags with the APPCLASS_MONITOR flag. + * For details, see the following Remarks section.

    + *
    + *
    APPCLASS_STANDARD
    + *
    0x00000000L
    + *
    + *
    + *

    + * Registers the application as a standard (nonmonitoring) DDEML + * application.

    + *
    + *
    APPCMD_CLIENTONLY
    + *
    0x00000010L
    + *
    + *
    + *

    + * Prevents the application from becoming a server in a DDE + * conversation. The application can only be a client. This flag reduces + * consumption of resources by the DDEML. It includes the functionality + * of the CBF_FAIL_ALLSVRXACTIONS flag.

    + *
    + *
    APPCMD_FILTERINITS
    + *
    0x00000020L
    + *
    + *
    + *

    + * Prevents the DDEML from sending XTYP_CONNECT and XTYP_WILDCONNECT + * transactions to the application until the application has created its + * string handles and registered its service names or has turned off + * filtering by a subsequent call to the DdeNameService or DdeInitialize + * function. This flag is always in effect when an application calls + * DdeInitialize for the first time, regardless of whether the + * application specifies the flag. On subsequent calls to DdeInitialize, + * not specifying this flag turns off the application's service-name + * filters, but specifying it turns on the application's service name + * filters.

    + *
    + *
    CBF_FAIL_ALLSVRXACTIONS
    + *
    0x0003f000
    + *
    + *
    + *

    + * Prevents the callback function from receiving server transactions. + * The system returns DDE_FNOTPROCESSED to each client that sends a + * transaction to this application. This flag is equivalent to combining + * all CBF_FAIL_ flags.

    + *
    + *
    CBF_FAIL_ADVISES
    + *
    0x00004000
    + *
    + *
    + *

    + * Prevents the callback function from receiving XTYP_ADVSTART and + * XTYP_ADVSTOP transactions. The system returns DDE_FNOTPROCESSED to + * each client that sends an XTYP_ADVSTART or XTYP_ADVSTOP transaction + * to the server.

    + *
    + *
    CBF_FAIL_CONNECTIONS
    + *
    0x00002000
    + *
    + *
    + *

    + * Prevents the callback function from receiving XTYP_CONNECT and + * XTYP_WILDCONNECT transactions.

    + *
    + *
    CBF_FAIL_EXECUTES
    + *
    0x00008000
    + *
    + *
    + *

    + * Prevents the callback function from receiving XTYP_EXECUTE + * transactions. The system returns DDE_FNOTPROCESSED to a client that + * sends an XTYP_EXECUTE transaction to the server.

    + *
    + *
    CBF_FAIL_POKES
    + *
    0x00010000
    + *
    + *
    + *

    + * Prevents the callback function from receiving XTYP_POKE transactions. + * The system returns DDE_FNOTPROCESSED to a client that sends an + * XTYP_POKE transaction to the server.

    + *
    + *
    CBF_FAIL_REQUESTS
    + *
    0x00020000
    + *
    + *
    + *

    + * Prevents the callback function from receiving XTYP_REQUEST + * transactions. The system returns DDE_FNOTPROCESSED to a client that + * sends an XTYP_REQUEST transaction to the server.

    + *
    + *
    CBF_FAIL_SELFCONNECTIONS
    + *
    0x00001000
    + *
    + *
    + *

    + * Prevents the callback function from receiving XTYP_CONNECT + * transactions from the application's own instance. This flag prevents + * an application from establishing a DDE conversation with its own + * instance. An application should use this flag if it needs to + * communicate with other instances of itself but not with itself.

    + *
    + *
    CBF_SKIP_ALLNOTIFICATIONS
    + *
    0x003c0000
    + *
    + *
    + *

    + * Prevents the callback function from receiving any notifications. This + * flag is equivalent to combining all CBF_SKIP_ flags.

    + *
    + *
    CBF_SKIP_CONNECT_CONFIRMS
    + *
    0x00040000
    + *
    + *
    + *

    + * Prevents the callback function from receiving XTYP_CONNECT_CONFIRM + * notifications.

    + *
    + *
    CBF_SKIP_DISCONNECTS
    + *
    0x00200000
    + *
    + *
    + *

    + * Prevents the callback function from receiving XTYP_DISCONNECT + * notifications.

    + *
    + *
    CBF_SKIP_REGISTRATIONS
    + *
    0x00080000
    + *
    + *
    + *

    + * Prevents the callback function from receiving XTYP_REGISTER + * notifications.

    + *
    + *
    CBF_SKIP_UNREGISTRATIONS
    + *
    0x00100000
    + *
    + *
    + *

    + * Prevents the callback function from receiving XTYP_UNREGISTER + * notifications.

    + *
    + *
    MF_CALLBACKS
    + *
    0x08000000
    + *
    + *
    + *

    + * Notifies the callback function whenever a transaction is sent to any + * DDE callback function in the system.

    + *
    + *
    MF_CONV
    + *
    0x40000000
    + *
    + *
    + *

    + * Notifies the callback function whenever a conversation is established + * or terminated.

    + *
    + *
    MF_ERRORS
    + *
    0x10000000
    + *
    + *
    + *

    + * Notifies the callback function whenever a DDE error occurs.

    + *
    + *
    MF_HSZ_INFO
    + *
    0x01000000
    + *
    + *
    + *

    + * Notifies the callback function whenever a DDE application creates, + * frees, or increments the usage count of a string handle or whenever a + * string handle is freed as a result of a call to the DdeUninitialize + * function.

    + *
    + *
    MF_LINKS
    + *
    0x20000000
    + *
    + *
    + *

    + * Notifies the callback function whenever an advise loop is started or + * ended.

    + *
    + *
    MF_POSTMSGS
    + *
    0x04000000
    + *
    + *
    + *

    + * Notifies the callback function whenever the system or an application + * posts a DDE message.

    + *
    + *
    MF_SENDMSGS
    + *
    0x02000000
    + *
    + *
    + *

    + * Notifies the callback function whenever the system or an application + * sends a DDE message.

    + *
    + * + *

    + * If the function failsa DdemlException is raised with one of the + * following errroCodes:

    + *
      + *
    • DMLERR_DLL_USAGE
    • + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_SYS_ERROR
    • + *
    + */ + public void initialize(int afCmd) throws DdemlException; + /** + * Creates a handle that identifies the specified string. A Dynamic Data + * Exchange (DDE) client or server application can pass the string + * handle as a parameter to other Dynamic Data Exchange Management + * Library (DDEML) functions. + * + * @param value The string for which a handle is to be + * created. This string can be up to 255 characters. The reason for this + * limit is that DDEML string management functions are implemented using + * atoms. + * + * @return If the function succeeds, the return value is a string + * handle. A parameter NULL will cause NULL to be returned. + * + *

    If the function fails, a DdemlException is raised with the + * corresponding errorCode:

    + *
      + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_NO_ERROR
    • + *
    • DMLERR_SYS_ERROR
    • + *
    + */ + public Ddeml.HSZ createStringHandle(String value) throws DdemlException; + + /** + * Copies text associated with a string handle into a buffer. + * + * @param value A handle to the string to copy. This handle must have been + * created by a previous call to the DdeCreateStringHandle function. + * @return String corresponding to the supplied handle + */ + public String queryString(Ddeml.HSZ value) throws DdemlException; + + /** + * Frees a string handle in the calling application. + * + * @param value A handle to the string handle to be freed. This handle + * must have been created by a previous call to the + * createStringHandle function. A NULL value will be silently ignored. + * + * @return true if the function succeeds. + */ + public boolean freeStringHandle(Ddeml.HSZ value); + + /** + * Increments the usage count associated with the specified handle. This + * function enables an application to save a string handle passed to the + * application's Dynamic Data Exchange (DDE) callback function. + * Otherwise, a string handle passed to the callback function is deleted + * when the callback function returns. This function should also be used + * to keep a copy of a string handle referenced by the CONVINFO + * structure returned by the DdeQueryConvInfo function. + * + * @param value A handle to the string handle to be saved. + * @return true if the function succeeded + */ + public boolean keepStringHandle(Ddeml.HSZ value); + + /** + * Registers or unregisters the service names a Dynamic Data Exchange + * (DDE) server supports. This function causes the system to send + * XTYP_REGISTER or XTYP_UNREGISTER transactions to other running + * Dynamic Data Exchange Management Library (DDEML) client applications. + * + * @param name A handle to the string that specifies the service name + * the server is registering or unregistering. An application that is + * unregistering all of its service names should set this parameter to + * 0L. + * @param afCmd The service name options. This parameter can be one of + * the following values. + * + * + * + * + * + * + * + *
    ValueMeaning
    DNS_REGISTERRegisters the error code service + * name.
    DNS_UNREGISTERUnregisters the error code service + * name. If the hsz1 parameter is 0L, all service names registered by + * the server will be unregistered.
    DNS_FILTERONTurns on service name initiation + * filtering. The filter prevents a server from receiving XTYP_CONNECT + * transactions for service names it has not registered. This is the + * default setting for this filter. + *

    + * If a server application does not register any service names, the + * application cannot receive XTYP_WILDCONNECT transactions. + *
    DNS_FILTEROFFTurns off service name initiation + * filtering. If this flag is specified, the server receives an + * XTYP_CONNECT transaction whenever another DDE application calls the + * DdeConnect function, regardless of the service name.
    + *

    + * If the function fails, a DdemlException is raised with the + * corresponding errorCode:

    + * + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_DLL_USAGE
    • + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_NO_ERROR
    • + *
    + */ + public void nameService(Ddeml.HSZ name, int afCmd) throws DdemlException; + + /** + * Registers or unregisters the service names a Dynamic Data Exchange + * (DDE) server supports. This function causes the system to send + * XTYP_REGISTER or XTYP_UNREGISTER transactions to other running + * Dynamic Data Exchange Management Library (DDEML) client applications. + * + * @param name A string that specifies the service name the server is + * registering or unregistering. An application that is unregistering + * all of its service names should set this parameter to NULL. + * @param afCmd The service name options. This parameter can be one of + * the following values. + * + * + * + * + * + * + * + *
    ValueMeaning
    DNS_REGISTERRegisters the error code service + * name.
    DNS_UNREGISTERUnregisters the error code service + * name. If the hsz1 parameter is 0L, all service names registered by + * the server will be unregistered.
    DNS_FILTERONTurns on service name initiation + * filtering. The filter prevents a server from receiving XTYP_CONNECT + * transactions for service names it has not registered. This is the + * default setting for this filter. + *

    + * If a server application does not register any service names, the + * application cannot receive XTYP_WILDCONNECT transactions. + *
    DNS_FILTEROFFTurns off service name initiation + * filtering. If this flag is specified, the server receives an + * XTYP_CONNECT transaction whenever another DDE application calls the + * DdeConnect function, regardless of the service name.
    + *

    + * If the function fails, a DdemlException is raised with the + * corresponding errorCode:

    + * + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_DLL_USAGE
    • + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_NO_ERROR
    • + *
    + */ + public void nameService(String name, int afCmd) throws DdemlException; + + /** + * @return See {@link Ddeml}.DMLERR_* + */ + public int getLastError(); + + /** + * Establishes a conversation with a server application that supports + * the specified service name and topic name pair. If more than one such + * server exists, the system selects only one. + * + * @param service A handle to the string that specifies the service + * name of the server application with which a conversation is to be + * established. This handle must have been created by a previous call to + * the DdeCreateStringHandle function. If this parameter is 0L, a + * conversation is established with any available server. + * + * @param topic A handle to the string that specifies the name of the + * topic on which a conversation is to be established. This handle must + * have been created by a previous call to DdeCreateStringHandle. If + * this parameter is 0L, a conversation on any topic supported by the + * selected server is established. + * + * @param convcontext A pointer to the CONVCONTEXT structure that contains + * conversation context information. If this parameter is NULL, the + * server receives the default CONVCONTEXT structure during the + * XTYP_CONNECT or XTYP_WILDCONNECT transaction. + * + * @return an established connection + * + *

    If the function fails, a DdemlException is raised with the + * corresponding errorCode:

    + * + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_NO_CONV_ESTABLISHED
    • + *
    • DMLERR_NO_ERROR
    • + *
    + */ + public IDdeConnection connect(Ddeml.HSZ service, Ddeml.HSZ topic, Ddeml.CONVCONTEXT convcontext); + + /** + * Establishes a conversation with a server application that supports + * the specified service name and topic name pair. If more than one such + * server exists, the system selects only one. + * + * @param service The service name of the server application with which + * a conversation is to be established. This handle must have been + * created by a previous call to the DdeCreateStringHandle function. If + * this parameter is 0L, a conversation is established with any + * available server. + * + * @param topic The name of the topic on which a conversation is to be + * established. This handle must have been created by a previous call to + * DdeCreateStringHandle. If this parameter is 0L, a conversation on any + * topic supported by the selected server is established. + * + * @param convcontext A pointer to the CONVCONTEXT structure that contains + * conversation context information. If this parameter is NULL, the + * server receives the default CONVCONTEXT structure during the + * XTYP_CONNECT or XTYP_WILDCONNECT transaction. + * + * @return an established connection + * + *

    If the function fails, a DdemlException is raised with the + * corresponding errorCode:

    + * + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_NO_CONV_ESTABLISHED
    • + *
    • DMLERR_NO_ERROR
    • + *
    + */ + public IDdeConnection connect(String service, String topic, Ddeml.CONVCONTEXT convcontext); + + /** + * Creates a Dynamic Data Exchange (DDE) object and fills the object + * with data from the specified buffer. A DDE application uses this + * function during transactions that involve passing data to the partner + * application. + * + * @param pSrc The data to be copied to the DDE object. If this + * parameter is NULL, no data is copied to the object. + * + * @param cb The amount of memory, in bytes, to copy from the buffer + * pointed to by pSrc. (include the terminating NULL, if the data is a + * string). If this parameter is zero, the pSrc parameter is ignored. + * + * @param cbOff An offset, in bytes, from the beginning of the buffer + * pointed to by the pSrc parameter. The data beginning at this offset + * is copied from the buffer to the DDE object. + * + * @param hszItem A handle to the string that specifies the data item + * corresponding to the DDE object. This handle must have been created + * by a previous call to the DdeCreateStringHandle function. If the data + * handle is to be used in an XTYP_EXECUTE transaction, this parameter + * must be 0L. + * + * @param wFmt The standard clipboard format of the data. + * + * @param afCmd The creation flags. This parameter can be + * HDATA_APPOWNED, which specifies that the server application calling + * the DdeCreateDataHandle function owns the data handle this function + * creates. This flag enables the application to share the data handle + * with other DDEML applications rather than creating a separate handle + * to pass to each application. If this flag is specified, the + * application must eventually free the shared memory object associated + * with the handle by using the DdeFreeDataHandle function. If this flag + * is not specified, the handle becomes invalid in the application that + * created the handle after the data handle is returned by the + * application's DDE callback function or is used as a parameter in + * another DDEML function. + * + * @return If the function succeeds, the return value is a data handle. + * + *

    + * If the function fails a DdeException is raised with the following + * errorCodes:

    + * + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_MEMORY_ERROR
    • + *
    • DMLERR_NO_ERROR
    • + *
    + */ + public Ddeml.HDDEDATA createDataHandle( + Pointer pSrc, + int cb, + int cbOff, + Ddeml.HSZ hszItem, + int wFmt, + int afCmd); + + /** + * Frees a Dynamic Data Exchange (DDE) object and deletes the data + * handle associated with the object. + * + * @param hData A handle to the DDE object to be freed. This handle must + * have been created by a previous call to the DdeCreateDataHandle + * function or returned by the DdeClientTransaction function. + * + *

    + * If the function fails a DdeException is raised with the following + * errorCodes:

    + * + *
      + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_NO_ERROR
    • + *
    + */ + public void freeDataHandle(Ddeml.HDDEDATA hData); + + /** + * Adds data to the specified Dynamic Data Exchange (DDE) object. An + * application can add data starting at any offset from the beginning of + * the object. If new data overlaps data already in the object, the new + * data overwrites the old data in the bytes where the overlap occurs. + * The contents of locations in the object that have not been written to + * are undefined. + * + * @param hData A handle to the DDE object that receives additional + * data. + * + * @param pSrc The data to be added to the DDE object. + * + * @param cb The length, in bytes, of the data to be added to the DDE + * object, including the terminating NULL, if the data is a string. + * + * @param cbOff An offset, in bytes, from the beginning of the DDE + * object. The additional data is copied to the object beginning at this + * offset. + * + * @return If the function succeeds, the return value is a new handle to + * the DDE object. The new handle is used in all references to the + * object. + * + *

    + * If the function fails a DdeException is raised with the following + * errorCodes:

    + * + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_MEMORY_ERROR
    • + *
    • DMLERR_NO_ERROR
    • + *
    + */ + public Ddeml.HDDEDATA addData(Ddeml.HDDEDATA hData, Pointer pSrc, int cb, int cbOff); + + /** + * Copies data from the specified Dynamic Data Exchange (DDE) object to + * the specified local buffer. + * + * @param hData A handle to the DDE object that contains the data to + * copy. + * + * @param pDst A pointer to the buffer that receives the data. If this + * parameter is NULL, the DdeGetData function returns the amount of + * data, in bytes, that would be copied to the buffer. + * + * @param cbMax The maximum amount of data, in bytes, to copy to the + * buffer pointed to by the pDst parameter. Typically, this parameter + * specifies the length of the buffer pointed to by pDst. + * + * @param cbOff An offset within the DDE object. Data is copied from the + * object beginning at this offset. + * + * @return If the pDst parameter points to a buffer, the return value is + * the size, in bytes, of the memory object associated with the data + * handle or the size specified in the cbMax parameter, whichever is + * lower. + * + *

    + * If the function fails a DdeException is raised with the following + * errorCodes:

    + * + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_NO_ERROR
    • + *
    + */ + public int getData(Ddeml.HDDEDATA hData, Pointer pDst, int cbMax, int cbOff); + + /** + * An application must call the DdeUnaccessData function when it has + * finished accessing the data in the object. + * + * @param hData A handle to the DDE object to be accessed. + * + * @param pcbDataSize A pointer to a variable that receives the size, in + * bytes, of the DDE object identified by the hData parameter. If this + * parameter is NULL, no size information is returned. + * + * @return If the function succeeds, the return value is a pointer to + * the first byte of data in the DDE object. + * + *

    + * If the function fails a DdeException is raised with the following + * errorCodes:

    + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_NO_ERROR
    • + *
    + */ + public Pointer accessData(Ddeml.HDDEDATA hData, WinDef.DWORDByReference pcbDataSize); + + /** + * Unaccesses a Dynamic Data Exchange (DDE) object. An application must + * call this function after it has finished accessing the object. + * + * @param hData A handle to the DDE object. + * + *

    + * If the function fails a DdeException is raised with the following + * errorCodes:

    + * + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_NO_ERROR
    • + *
    + */ + public void unaccessData(Ddeml.HDDEDATA hData); + + /** + * Causes the system to send an XTYP_ADVREQ transaction to the calling + * (server) application's Dynamic Data Exchange (DDE) callback function + * for each client with an active advise loop on the specified topic and + * item. A server application should call this function whenever the + * data associated with the topic name or item name pair changes. + * + * @param hszTopic A handle to a string that specifies the topic name. + * To send notifications for all topics with active advise loops, an + * application can set this parameter to 0L. + * + * @param hszItem A handle to a string that specifies the item name. To + * send notifications for all items with active advise loops, an + * application can set this parameter to 0L. + * + *

    + * If the function fails a DdeException is raised with the following + * errorCodes:

    + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_DLL_USAGE
    • + *
    • DMLERR_NO_ERROR
    • + *
    + * + */ + public void postAdvise(Ddeml.HSZ hszTopic, Ddeml.HSZ hszItem); + + /** + * Causes the system to send an XTYP_ADVREQ transaction to the calling + * (server) application's Dynamic Data Exchange (DDE) callback function + * for each client with an active advise loop on the specified topic and + * item. A server application should call this function whenever the + * data associated with the topic name or item name pair changes. + * + * @param hszTopic A string that specifies the topic name. To send + * notifications for all topics with active advise loops, an application + * can set this parameter to NULL. + * + * @param hszItem A string that specifies the item name. To send + * notifications for all items with active advise loops, an application + * can set this parameter to NULL. + * + *

    + * If the function fails a DdeException is raised with the following + * errorCodes:

    + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_DLL_USAGE
    • + *
    • DMLERR_NO_ERROR
    • + *
    + * + */ + public void postAdvise(String hszTopic, String hszItem); + + /** + * Abandons all asynchronous transaction and releases all + * resources associated with the transaction. + * + *

    + * If the method fails a DdeException will be raised with the + * corresponding errorCode:

    + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_NO_ERROR
    • + *
    • DMLERR_UNFOUND_QUEUE_ID
    • + *
    + */ + public void abandonTransactions(); + + /** + * Establishes a conversation with all server applications that support + * the specified service name and topic name pair. An application can + * also use this function to obtain a list of conversation handles by + * passing the function an existing conversation handle. The Dynamic + * Data Exchange Management Library removes the handles of any + * terminated conversations from the conversation list. The resulting + * conversation list contains the handles of all currently established + * conversations that support the specified service name and topic name. + * + * @param service A handle to the string that specifies the service + * name of the server application with which a conversation is to be + * established. If this parameter is 0L, the system attempts to + * establish conversations with all available servers that support the + * specified topic name. + * + * @param topic A handle to the string that specifies the name of the + * topic on which a conversation is to be established. This handle must + * have been created by a previous call to the DdeCreateStringHandle + * function. If this parameter is 0L, the system will attempt to + * establish conversations on all topics supported by the selected + * server (or servers). + * + * @param existingList An existinct conversation list to be enumerated. + * This parameter should be NULL if a new conversation list is to be + * established. + * + * @param ctx A pointer to the CONVCONTEXT structure that contains + * conversation-context information. If this parameter is NULL, the + * server receives the default CONVCONTEXT structure during the + * XTYP_CONNECT or XTYP_WILDCONNECT transaction. + * + * @return The new ConnectionList + * + *

    + * If the function fails a DdeException is raised with the + * appropriate errorCode:

    + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_NO_CONV_ESTABLISHED
    • + *
    • DMLERR_NO_ERROR
    • + *
    • DMLERR_SYS_ERROR
    • + *
    + */ + public IDdeConnectionList connectList(Ddeml.HSZ service, Ddeml.HSZ topic, IDdeConnectionList existingList, Ddeml.CONVCONTEXT ctx); + + /** + * Establishes a conversation with all server applications that support + * the specified service name and topic name pair. An application can + * also use this function to obtain a list of conversation handles by + * passing the function an existing conversation handle. The Dynamic + * Data Exchange Management Library removes the handles of any + * terminated conversations from the conversation list. The resulting + * conversation list contains the handles of all currently established + * conversations that support the specified service name and topic name. + * + * @param service A string that specifies the service name of the server + * application with which a conversation is to be established. If this + * parameter is 0L, the system attempts to establish conversations with + * all available servers that support the specified topic name. + * + * @param topic A string that specifies the name of the topic on which a + * conversation is to be established. This handle must have been created + * by a previous call to the DdeCreateStringHandle function. If this + * parameter is 0L, the system will attempt to establish conversations + * on all topics supported by the selected server (or servers). + * + * @param existingList An existinct conversation list to be enumerated. + * This parameter should be NULL if a new conversation list is to be + * established. + * + * @param ctx A pointer to the CONVCONTEXT structure that contains + * conversation-context information. If this parameter is NULL, the + * server receives the default CONVCONTEXT structure during the + * XTYP_CONNECT or XTYP_WILDCONNECT transaction. + * + * @return The new ConnectionList + * + *

    + * If the function fails a DdeException is raised with the + * appropriate errorCode:

    + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_NO_CONV_ESTABLISHED
    • + *
    • DMLERR_NO_ERROR
    • + *
    • DMLERR_SYS_ERROR
    • + *
    + */ + public IDdeConnectionList connectList(String service, String topic, IDdeConnectionList existingList, Ddeml.CONVCONTEXT ctx); + + /** + * Enables or disables transactions for a specific conversation or for + * all conversations currently established by the calling application. + * + * @param wCmd The function code. This parameter can be one of the + * following values. + * + * + * + * + * + * + *
    ValueMeaning
    EC_ENABLEALLEnables all transactions for the + * specified conversation.
    EC_ENABLEONEEnables one transaction for the + * specified conversation.
    EC_DISABLEDisables all blockable transactions for + * the specified conversation. + * + *

    + * A server application can disable the following transactions:

    + *
      + *
    • XTYP_ADVSTART
    • + *
    • XTYP_ADVSTOP
    • + *
    • XTYP_EXECUTE
    • + *
    • XTYP_POKE
    • + *
    • XTYP_REQUEST
    • + *
    + *

    + * A client application can disable the following transactions:

    + *
      + *
    • XTYP_ADVDATA
    • + *
    • XTYP_XACT_COMPLETE
    • + *
    + *
    EC_QUERYWAITINGDetermines whether any transactions + * are in the queue for the specified conversation.
    + * + * @return If the function succeeds, the return value is nonzero. + * + *

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

    + * + *

    + * If the wCmd parameter is EC_QUERYWAITING, and the application + * transaction queue contains one or more unprocessed transactions that + * are not being processed, the return value is TRUE; otherwise, it is + * FALSE.

    + * + *

    + * If the function fails a DdeException is raised with the + * appropriate errorCode:

    + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_NO_ERROR
    • + *
    + */ + public boolean enableCallback(int wCmd); + + /** + * Frees all Dynamic Data Exchange Management Library (DDEML) resources + * associated with the calling application. + * + * @return true if function succeeded + */ + public boolean uninitialize(); + + /** + * Wrap a connection handle into a IDdeConnection helper class. + * + * @param conv HCONV structure to wrap + * @return wrapped IDdeConnection + */ + public IDdeConnection wrap(HCONV conv); + + public void registerAdvstartHandler(AdvstartHandler handler); + + public void unregisterAdvstartHandler(AdvstartHandler handler); + + public void registerAdvstopHandler(AdvstopHandler handler); + + public void unregisterAdvstopHandler(AdvstopHandler handler); + + public void registerConnectHandler(ConnectHandler handler); + + public void unregisterConnectHandler(ConnectHandler handler); + + public void registerAdvReqHandler(AdvreqHandler handler); + + public void unregisterAdvReqHandler(AdvreqHandler handler); + + public void registerRequestHandler(RequestHandler handler); + + public void unregisterRequestHandler(RequestHandler handler); + + public void registerWildconnectHandler(WildconnectHandler handler); + + public void unregisterWildconnectHandler(WildconnectHandler handler); + + public void registerAdvdataHandler(AdvdataHandler handler); + + public void unregisterAdvdataHandler(AdvdataHandler handler); + + public void registerExecuteHandler(ExecuteHandler handler); + + public void unregisterExecuteHandler(ExecuteHandler handler); + + public void registerPokeHandler(PokeHandler handler); + + public void unregisterPokeHandler(PokeHandler handler); + + public void registerConnectConfirmHandler(ConnectConfirmHandler handler); + + public void unregisterConnectConfirmHandler(ConnectConfirmHandler handler); + + public void registerDisconnectHandler(DisconnectHandler handler); + + public void unregisterDisconnectHandler(DisconnectHandler handler); + + public void registerErrorHandler(ErrorHandler handler); + + public void unregisterErrorHandler(ErrorHandler handler); + + public void registerRegisterHandler(RegisterHandler handler); + + public void unregisterRegisterHandler(RegisterHandler handler); + + public void registerXactCompleteHandler(XactCompleteHandler handler); + + public void unregisterXactCompleteHandler(XactCompleteHandler handler); + + public void registerUnregisterHandler(UnregisterHandler handler); + + public void unregisterUnregisterHandler(UnregisterHandler handler); + + public void registerMonitorHandler(MonitorHandler handler); + + public void unregisterMonitorHandler(MonitorHandler handler); + } + + /** + * The IDdeConnectionList wraps a connectionlist. + */ + public interface IDdeConnectionList extends Closeable { + public Ddeml.HCONVLIST getHandle(); + + /** + * Retrieves the next conversation handle in the specified conversation + * list. + * + * @param prevConnection A handle to the conversation handle previously + * returned by this function. If this parameter is NULL, the function + * returns the first conversation handle in the list. + * + * @return If the list contains any more conversation handles, the + * return value is the next conversation IDdeConnection in the list; + * otherwise it is NULL. + */ + public IDdeConnection queryNextServer(IDdeConnection prevConnection); + + /** + * Destroys the specified conversation list and terminates all + * conversations associated with the list. + * + *

    + * If the function fails a DdeException is raised with the + * appropriate errorCode:

    + * + *
      + *
    • DMLERR_DLL_NOT_INITIALIZED
    • + *
    • DMLERR_INVALIDPARAMETER
    • + *
    • DMLERR_NO_ERROR
    • + *
    + * + *

    Note: This wraps DdeDisconnectList to align with Closeable wording.

    + */ + public void close(); + } +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/DsGetDC.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/DsGetDC.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/DsGetDC.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/DsGetDC.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,33 +1,42 @@ /* 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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 java.util.Arrays; import java.util.List; import com.sun.jna.Pointer; import com.sun.jna.Structure; -import com.sun.jna.WString; import com.sun.jna.platform.win32.Guid.GUID; import com.sun.jna.platform.win32.WinNT.PSID; -import com.sun.jna.win32.StdCallLibrary; +import com.sun.jna.win32.W32APITypeMapper; /** * Ported from DsGetDC.h. Windows SDK 6.0a - * + * * @author dblock[at]dblock.org */ -public interface DsGetDC extends StdCallLibrary { +public interface DsGetDC { /** * The DOMAIN_CONTROLLER_INFO structure is used with the DsGetDcName @@ -39,16 +48,13 @@ implements Structure.ByReference { } - public DOMAIN_CONTROLLER_INFO() { - } - - public DOMAIN_CONTROLLER_INFO(Pointer memory) { - super(memory); - read(); - } + public static final List FIELDS = createFieldsOrder("DomainControllerName", + "DomainControllerAddress", "DomainControllerAddressType", + "DomainGuid", "DomainName", "DnsForestName", "Flags", + "DcSiteName", "ClientSiteName"); /** - * Pointer to a null-terminated WString that specifies the computer name + * Pointer to a null-terminated string that specifies the computer name * of the discovered domain controller. The returned computer name is * prefixed with "\\". The DNS-style name, for example, * "\\phoenix.fabrikam.com", is returned, if available. If the DNS-style @@ -57,16 +63,16 @@ * 4.0 domain or if the domain does not support the IP family of * protocols. */ - public WString DomainControllerName; + public String DomainControllerName; /** - * Pointer to a null-terminated WString that specifies the address of + * Pointer to a null-terminated string that specifies the address of * the discovered domain controller. The address is prefixed with "\\". - * This WString is one of the types defined by the + * This string is one of the types defined by the * DomainControllerAddressType member. */ - public WString DomainControllerAddress; + public String DomainControllerAddress; /** - * Indicates the type of WString that is contained in the + * Indicates the type of string that is contained in the * DomainControllerAddress member. */ public int DomainControllerAddressType; @@ -77,46 +83,53 @@ */ public GUID DomainGuid; /** - * Pointer to a null-terminated WString that specifies the name of the + * Pointer to a null-terminated string that specifies the name of the * domain. The DNS-style name, for example, "fabrikam.com", is returned * if available. Otherwise, the flat-style name, for example, * "fabrikam", is returned. This name may be different than the * requested domain name if the domain has been renamed. */ - public WString DomainName; + public String DomainName; /** - * Pointer to a null-terminated WString that specifies the name of the + * Pointer to a null-terminated string that specifies the name of the * domain at the root of the DS tree. The DNS-style name, for example, * "fabrikam.com", is returned if available. Otherwise, the flat-style * name, for example, "fabrikam" is returned. */ - public WString DnsForestName; + public String DnsForestName; /** * Contains a set of flags that describe the domain controller. */ public int Flags; /** - * Pointer to a null-terminated WString that specifies the name of the + * Pointer to a null-terminated string that specifies the name of the * site where the domain controller is located. This member may be NULL * if the domain controller is not in a site; for example, the domain * controller is a Windows NT 4.0 domain controller. */ - public WString DcSiteName; + public String DcSiteName; /** - * Pointer to a null-terminated WString that specifies the name of the + * Pointer to a null-terminated string that specifies the name of the * site that the computer belongs to. The computer is specified in the * ComputerName parameter passed to DsGetDcName. This member may be NULL * if the site that contains the computer cannot be found; for example, * if the DS administrator has not associated the subnet that the * computer is in with a valid site. */ - public WString ClientSiteName; + public String ClientSiteName; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "DomainControllerName", - "DomainControllerAddress", "DomainControllerAddressType", - "DomainGuid", "DomainName", "DnsForestName", "Flags", - "DcSiteName", "ClientSiteName" }); + public DOMAIN_CONTROLLER_INFO() { + super(W32APITypeMapper.DEFAULT); + } + + public DOMAIN_CONTROLLER_INFO(Pointer memory) { + super(memory, Structure.ALIGN_DEFAULT, W32APITypeMapper.DEFAULT); + read(); + } + + @Override + protected List getFieldOrder() { + return FIELDS; } } @@ -130,10 +143,13 @@ } + public static final List FIELDS = createFieldsOrder("dci"); + public DOMAIN_CONTROLLER_INFO.ByReference dci; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "dci" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } @@ -178,16 +194,20 @@ Structure.ByReference { } + public static final List FIELDS = createFieldsOrder("NetbiosDomainName", + "DnsDomainName", "Flags", "ParentIndex", "TrustType", + "TrustAttributes", "DomainSid", "DomainGuid"); + /** * Pointer to a null-terminated string that contains the NetBIOS name of * the domain. */ - public WString NetbiosDomainName; + public String NetbiosDomainName; /** * Pointer to a null-terminated string that contains the DNS name of the * domain. This member may be NULL. */ - public WString DnsDomainName; + public String DnsDomainName; /** * Contains a set of flags that specify more data about the domain * trust. @@ -221,17 +241,17 @@ */ public GUID DomainGuid; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "NetbiosDomainName", - "DnsDomainName", "Flags", "ParentIndex", "TrustType", - "TrustAttributes", "DomainSid", "DomainGuid" }); + @Override + protected List getFieldOrder() { + return FIELDS; } public DS_DOMAIN_TRUSTS() { + super(W32APITypeMapper.DEFAULT); } public DS_DOMAIN_TRUSTS(Pointer p) { - super(p); + super(p, Structure.ALIGN_DEFAULT, W32APITypeMapper.DEFAULT); read(); } }; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Dxva2.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Dxva2.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Dxva2.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Dxva2.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,22 +1,33 @@ /* * Copyright 2014 Martin Steiger * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * 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 java.util.Collections; import java.util.HashMap; +import java.util.Map; import com.sun.jna.DefaultTypeMapper; import com.sun.jna.Library; @@ -35,49 +46,49 @@ * A port of dxva2.dll * @author Martin Steiger */ -public interface Dxva2 extends StdCallLibrary, PhysicalMonitorEnumerationAPI, HighLevelMonitorConfigurationAPI, LowLevelMonitorConfigurationAPI -{ +public interface Dxva2 extends StdCallLibrary, PhysicalMonitorEnumerationAPI, HighLevelMonitorConfigurationAPI, LowLevelMonitorConfigurationAPI { + Map DXVA_OPTIONS = Collections.unmodifiableMap(new HashMap() { + private static final long serialVersionUID = -1987971664975780480L; + + { + 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)); + } + }); + } + }); + /** * The only instance of the library */ - Dxva2 INSTANCE = (Dxva2) Native.loadLibrary("Dxva2", Dxva2.class, new HashMap() - { - private static final long serialVersionUID = -1987971664975780480L; - - { - 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)); - } - }); - } - }); + Dxva2 INSTANCE = Native.loadLibrary("Dxva2", Dxva2.class, DXVA_OPTIONS); /****************************************************************************** - Monitor capability functions + Monitor capability functions ******************************************************************************/ /** - * Retrieves the configuration capabilities of a monitor. Call this function to find out which high-level + * Retrieves the configuration capabilities of a monitor. Call this function to find out which high-level * monitor configuration functions are supported by the monitor. - * @param hMonitor Handle to a physical monitor. To get the monitor handle, call + * @param hMonitor Handle to a physical monitor. To get the monitor handle, call * {@link #GetPhysicalMonitorsFromHMONITOR} * @param pdwMonitorCapabilities Receives a bitwise OR of capabilities flags. (MC_CAPS_*) - * @param pdwSupportedColorTemperatures Receives a bitwise OR of color temperature flags. + * @param pdwSupportedColorTemperatures Receives a bitwise OR of color temperature flags. * (MC_SUPPORTED_COLOR_TEMPERATURE_*) - * @return If the function succeeds, the return value is TRUE. If the function fails, the return value is - * FALSE. To get extended error information, call GetLastError. - * + * @return If the function succeeds, the return value is TRUE. If the function fails, the return value is + * FALSE. To get extended error information, call GetLastError. + * *

    The function fails if the monitor does not support DDC/CI.

    */ BOOL GetMonitorCapabilities(HANDLE hMonitor, DWORDByReference pdwMonitorCapabilities, DWORDByReference pdwSupportedColorTemperatures); /****************************************************************************** - Monitor setting persistence functions + Monitor setting persistence functions ******************************************************************************/ /** @@ -96,11 +107,11 @@ /** * Retrieves the type of technology used by a monitor. - * This function does not support every display technology. If a monitor uses a display technology that is - * supported by this function, the GetMonitorCapabilities function returns the MC_CAPS_DISPLAY_TECHNOLOGY_TYPE + * This function does not support every display technology. If a monitor uses a display technology that is + * supported by this function, the GetMonitorCapabilities function returns the MC_CAPS_DISPLAY_TECHNOLOGY_TYPE * flag. If that flag is absent, the GetMonitorTechnologyType function fails. - * Some monitor technologies do not support certain monitor configuration functions. For example, - * the DegaussMonitor function is supported only for cathode ray tube (CRT) monitors. To find out whether a + * Some monitor technologies do not support certain monitor configuration functions. For example, + * the DegaussMonitor function is supported only for cathode ray tube (CRT) monitors. To find out whether a * specific function is supported, call GetMonitorCapabilities. * @param hMonitor Handle to a physical monitor. To get the monitor handle, call GetPhysicalMonitorsFromHMONITOR * @param pdtyDisplayTechnologyType Receives the technology type as defined in {@link HighLevelMonitorConfigurationAPI.MC_DISPLAY_TECHNOLOGY_TYPE}. @@ -109,7 +120,7 @@ BOOL GetMonitorTechnologyType(HANDLE hMonitor, MC_DISPLAY_TECHNOLOGY_TYPE.ByReference pdtyDisplayTechnologyType); /****************************************************************************** - Monitor image calibration functions + Monitor image calibration functions ******************************************************************************/ /** @@ -151,8 +162,8 @@ /** * Retrieves a monitor's red, green, or blue drive value. *

    - * Drive settings are generally used to adjust the monitor's white point. Drive and black level are different - * names for the same monitor setting. If this function is supported, the GetMonitorCapabilities function returns + * Drive settings are generally used to adjust the monitor's white point. Drive and black level are different + * names for the same monitor setting. If this function is supported, the GetMonitorCapabilities function returns * the MC_CAPS_RED_GREEN_BLUE_DRIVE flag.

    * @param hMonitor Handle to a physical monitor. * @param dtDriveType A member of the MC_DRIVE_TYPE enumeration, specifying whether to retrieve the red, green, or blue drive value. @@ -167,7 +178,7 @@ /** * Retrieves a monitor's red, green, or blue gain value. *

    - * Gain settings are generally used to adjust the monitor's white point. If this function is supported, the + * Gain settings are generally used to adjust the monitor's white point. If this function is supported, the * GetMonitorCapabilities function returns the MC_CAPS_RED_GREEN_BLUE_GAIN flag. This function takes about 40 milliseconds to return. * The gain settings are continuous monitor settings.

    * @param hMonitor Handle to a physical monitor. @@ -206,10 +217,10 @@ /** * Sets a monitor's color temperature. *

    - * If this function is supported, the GetMonitorCapabilities function returns the MC_CAPS_COLOR_TEMPERATURE flag. - * The GetMonitorCapabilities function also returns the range of color temperatures that the monitor supports. - * The ctCurrentColorTemperature parameter must correspond to one of these values. Changing the color temperature - * changes the monitor's white point. It can also change the current drive and gain settings. To get the new drive + * If this function is supported, the GetMonitorCapabilities function returns the MC_CAPS_COLOR_TEMPERATURE flag. + * The GetMonitorCapabilities function also returns the range of color temperatures that the monitor supports. + * The ctCurrentColorTemperature parameter must correspond to one of these values. Changing the color temperature + * changes the monitor's white point. It can also change the current drive and gain settings. To get the new drive * and gain settings, call GetMonitorRedGreenOrBlueDrive and GetMonitorRedGreenOrBlueGain, respectively. * This function takes from 50 to 90 milliseconds to return.

    * @param hMonitor Handle to a physical monitor. @@ -219,7 +230,7 @@ BOOL SetMonitorColorTemperature(HANDLE hMonitor, MC_COLOR_TEMPERATURE ctCurrentColorTemperature); /** - * Sets a monitor's red, green, or blue drive value. + * Sets a monitor's red, green, or blue drive value. *

    * Drive settings are generally used to adjust the * monitor's white point. Drive and black level are different names for the same monitor setting. If this function @@ -236,7 +247,7 @@ BOOL SetMonitorRedGreenOrBlueDrive(HANDLE hMonitor, MC_DRIVE_TYPE dtDriveType, int dwNewDrive); /** - * Sets a monitor's red, green, or blue gain value. + * Sets a monitor's red, green, or blue gain value. *

    * Gain settings are generally used to adjust the * monitor's white point. If this function is supported, the GetMonitorCapabilities function returns the @@ -274,10 +285,10 @@ * If this function is supported, the GetMonitorCapabilities function returns the MC_CAPS_DISPLAY_AREA_SIZE flag. * This function takes about 40 milliseconds to return. The width and height settings are continuous monitor settings.

    * @param hMonitor Handle to a physical monitor. To get the monitor handle, call GetPhysicalMonitorsFromHMONITOR - * @param stSizeType A member of the MC_SIZE_TYPE enumeration, specifying whether to retrieve the width or the height. - * @param pdwMinimumWidthOrHeight Receives the minimum width or height. - * @param pdwCurrentWidthOrHeight Receives the current width or height. - * @param pdwMaximumWidthOrHeight Receives the maximum width or height. + * @param stSizeType A member of the MC_SIZE_TYPE enumeration, specifying whether to retrieve the width or the height. + * @param pdwMinimumWidthOrHeight Receives the minimum width or height. + * @param pdwCurrentWidthOrHeight Receives the current width or height. + * @param pdwMaximumWidthOrHeight Receives the maximum width or height. * @return If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. */ BOOL GetMonitorDisplayAreaSize(HANDLE hMonitor, MC_SIZE_TYPE stSizeType, DWORDByReference pdwMinimumWidthOrHeight, @@ -289,10 +300,10 @@ * If this function is supported, the GetMonitorCapabilities function returns the MC_CAPS_DISPLAY_AREA_POSITION flag. * This function takes about 40 milliseconds to return. The horizontal and vertical position are continuous monitor settings.

    * @param hMonitor Handle to a physical monitor. To get the monitor handle, call GetPhysicalMonitorsFromHMONITOR - * @param ptPositionType A member of the MC_POSITION_TYPE enumeration, specifying whether to retrieve the horizontal position or the vertical position. - * @param pdwMinimumPosition Receives the minimum horizontal or vertical position. - * @param pdwCurrentPosition Receives the current horizontal or vertical position. - * @param pdwMaximumPosition Receives the maximum horizontal or vertical position. + * @param ptPositionType A member of the MC_POSITION_TYPE enumeration, specifying whether to retrieve the horizontal position or the vertical position. + * @param pdwMinimumPosition Receives the minimum horizontal or vertical position. + * @param pdwCurrentPosition Receives the current horizontal or vertical position. + * @param pdwMaximumPosition Receives the maximum horizontal or vertical position. * @return If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. */ BOOL GetMonitorDisplayAreaPosition(HANDLE hMonitor, MC_POSITION_TYPE ptPositionType, @@ -305,9 +316,9 @@ * If this function is supported, the GetMonitorCapabilities function returns the MC_CAPS_DISPLAY_AREA_SIZE flag. * This function takes about 50 milliseconds to return. The width and height settings are continuous monitor settings.

    * @param hMonitor Handle to a physical monitor. To get the monitor handle, call GetPhysicalMonitorsFromHMONITOR - * @param stSizeType A member of the MC_SIZE_TYPE enumeration, specifying whether to set the width or the height. - * @param dwNewDisplayAreaWidthOrHeight Display area width or height. To get the minimum and maximum width and height, - * call GetMonitorDisplayAreaSize. + * @param stSizeType A member of the MC_SIZE_TYPE enumeration, specifying whether to set the width or the height. + * @param dwNewDisplayAreaWidthOrHeight Display area width or height. To get the minimum and maximum width and height, + * call GetMonitorDisplayAreaSize. * @return If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. */ BOOL SetMonitorDisplayAreaSize(HANDLE hMonitor, MC_SIZE_TYPE stSizeType, int dwNewDisplayAreaWidthOrHeight); @@ -318,8 +329,8 @@ * If this function is supported, the GetMonitorCapabilities function returns the MC_CAPS_DISPLAY_AREA_POSITION flag. * This function takes about 50 milliseconds to return. The horizontal and vertical position are continuous monitor settings.

    * @param hMonitor Handle to a physical monitor. To get the monitor handle, call GetPhysicalMonitorsFromHMONITOR - * @param ptPositionType A member of the MC_POSITION_TYPE enumeration, specifying whether to set the horizontal position or the vertical position. - * @param dwNewPosition Horizontal or vertical position. To get the minimum and maximum position, call GetMonitorDisplayAreaPosition. + * @param ptPositionType A member of the MC_POSITION_TYPE enumeration, specifying whether to set the horizontal position or the vertical position. + * @param dwNewPosition Horizontal or vertical position. To get the minimum and maximum position, call GetMonitorDisplayAreaPosition. * @return If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. */ BOOL SetMonitorDisplayAreaPosition(HANDLE hMonitor, MC_POSITION_TYPE ptPositionType, int dwNewPosition); @@ -368,18 +379,18 @@ /** * Retrieves the current value, maximum value, and code type of a Virtual Control Panel (VCP) code for a monitor. - * This function corresponds to the "Get VCP Feature & VCP Feature Reply" command from the Display Data + * This function corresponds to the "Get VCP Feature & VCP Feature Reply" command from the Display Data * Channel Command Interface (DDC/CI) standard. Vendor-specific VCP codes can be used with this function. - * This function takes about 40 milliseconds to return. + * This function takes about 40 milliseconds to return. * @param hMonitor Handle to a physical monitor. To get the monitor handle, call GetPhysicalMonitorsFromHMONITOR * @param bVCPCode VCP code to query. The VCP codes are Include the VESA Monitor Control Command Set (MCCS) - * standard, versions 1.0 and 2.0. This parameter must specify a continuous or non-continuous VCP, or a + * standard, versions 1.0 and 2.0. This parameter must specify a continuous or non-continuous VCP, or a * vendor-specific code. It should not be a table control code. - * @param pvct Receives the VCP code type, as a member of the MC_VCP_CODE_TYPE enumeration. This parameter can be NULL. - * @param pdwCurrentValue Receives the current value of the VCP code. This parameter can be NULL. - * @param pdwMaximumValue If bVCPCode specifies a continuous VCP code, this parameter receives the maximum value of - * the VCP code. If bVCPCode specifies a non-continuous VCP code, the value received in this parameter - * is undefined. This parameter can be NULL. + * @param pvct Receives the VCP code type, as a member of the MC_VCP_CODE_TYPE enumeration. This parameter can be NULL. + * @param pdwCurrentValue Receives the current value of the VCP code. This parameter can be NULL. + * @param pdwMaximumValue If bVCPCode specifies a continuous VCP code, this parameter receives the maximum value of + * the VCP code. If bVCPCode specifies a non-continuous VCP code, the value received in this parameter + * is undefined. This parameter can be NULL. * @return If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. */ BOOL GetVCPFeatureAndVCPFeatureReply(HANDLE hMonitor, BYTE bVCPCode, MC_VCP_CODE_TYPE.ByReference pvct, @@ -410,9 +421,9 @@ /** * Retrieves the length of a monitor's capabilities string. - * This function usually returns quickly, but sometimes it can take several seconds to complete. + * This function usually returns quickly, but sometimes it can take several seconds to complete. * @param hMonitor Handle to a physical monitor. To get the monitor handle, call GetPhysicalMonitorsFromHMONITOR - * @param pdwCapabilitiesStringLengthInCharacters Receives the length of the capabilities string, in characters, including the terminating null character. + * @param pdwCapabilitiesStringLengthInCharacters Receives the length of the capabilities string, in characters, including the terminating null character. * @return If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. */ BOOL GetCapabilitiesStringLength(HANDLE hMonitor, DWORDByReference pdwCapabilitiesStringLengthInCharacters); @@ -499,7 +510,7 @@ /** * Closes an array of physical monitor handles. - * Call this function to close an array of monitor handles obtained from the GetPhysicalMonitorsFromHMONITOR + * Call this function to close an array of monitor handles obtained from the GetPhysicalMonitorsFromHMONITOR * @param dwPhysicalMonitorArraySize Number of elements in the pPhysicalMonitorArray array. * @param pPhysicalMonitorArray Pointer to an array of PHYSICAL_MONITOR structures. * @return If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/FlagEnum.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/FlagEnum.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/FlagEnum.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/FlagEnum.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,17 +1,26 @@ /* * Copyright 2014 Martin Steiger * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * 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; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/GDI32.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/GDI32.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/GDI32.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/GDI32.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

    - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; @@ -39,9 +50,14 @@ */ public interface GDI32 extends StdCallLibrary { - GDI32 INSTANCE = (GDI32) Native.loadLibrary("gdi32", GDI32.class, - W32APIOptions.DEFAULT_OPTIONS); + GDI32 INSTANCE = Native.loadLibrary("gdi32", GDI32.class, W32APIOptions.DEFAULT_OPTIONS); + /** + * Used with BitBlt. Copies the source rectangle directly to the destination + * rectangle. + */ + int SRCCOPY = 0xCC0020; + /** * The ExtCreateRegion function creates a region from the specified region and transformation data. * @param lpXform @@ -430,4 +446,148 @@ */ public int GetObject(final HANDLE hgdiobj, final int cbBuffer, final Pointer lpvObject); + + /** + * The BitBlt function performs a bit-block transfer of the color data + * corresponding to a rectangle of pixels from the specified source device + * context into a destination device context. + * + * @param hdcDest + * A handle to the destination device context. + * @param nXDest + * The x-coordinate, in logical units, of the upper-left corner + * of the destination rectangle. + * @param nYDest + * The y-coordinate, in logical units, of the upper-left corner + * of the destination rectangle. + * @param nWidth + * The width, in logical units, of the source and destination + * rectangles. + * @param nHeight + * The height, in logical units, of the source and the + * destination rectangles. + * @param hdcSrc + * A handle to the source device context. + * @param nXSrc + * The x-coordinate, in logical units, of the upper-left corner + * of the source rectangle. + * @param nYSrc + * The y-coordinate, in logical units, of the upper-left corner + * of the source rectangle. + * @param dwRop + * A raster-operation code.
    + * These codes define how the color data for the source rectangle + * is to be combined with the color data for the destination + * rectangle to achieve the final color.
    + * The following list shows some common raster operation codes. + *
    + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
    ValueMeaning
    BLACKNESSFills the destination rectangle using the color associated + * with index 0 in the physical palette. (This color is black for + * the default physical palette.)
    CAPTUREBLTIncludes any windows that are layered on top of your + * window in the resulting image. By default, the image only + * contains your window. Note that this generally cannot be used + * for printing device contexts.
    DSTINVERTInverts the destination rectangle.
    MERGECOPYMerges the colors of the source rectangle with the brush + * currently selected in hdcDest, by using the Boolean + * AND operator.
    MERGEPAINTMerges the colors of the inverted source rectangle with + * the colors of the destination rectangle by using the Boolean + * OR operator.
    NOMIRRORBITMAP + * Prevents the bitmap from being mirrored.
    NOTSRCCOPYCopies the inverted source rectangle to the destination. + *
    NOTSRCERASECombines the colors of the source and destination + * rectangles by using the Boolean OR operator and then inverts + * the resultant color.
    PATCOPYCopies the brush currently selected in hdcDest, + * into the destination bitmap.
    PATINVERTCombines the colors of the brush currently selected in + * hdcDest, with the colors of the destination rectangle + * by using the Boolean XOR operator.
    PATPAINTCombines the colors of the brush currently selected in + * hdcDest, with the colors of the inverted source + * rectangle by using the Boolean OR operator. The result of this + * operation is combined with the colors of the destination + * rectangle by using the Boolean OR operator.
    SRCANDCombines the colors of the source and destination + * rectangles by using the Boolean AND operator.
    SRCCOPYCopies the source rectangle directly to the destination + * rectangle.
    SRCERASECombines the inverted colors of the destination rectangle + * with the colors of the source rectangle by using the Boolean + * AND operator.
    SRCINVERTCombines the colors of the source and destination + * rectangles by using the Boolean XOR operator.
    SRCPAINTCombines the colors of the source and destination + * rectangles by using the Boolean OR operator.
    WHITENESSFills the destination rectangle using the color associated + * with index 1 in the physical palette. (This color is white for + * the default physical palette.)
    + * @return True if the function succeeded, False if not. To get extended + * error information, call GetLastError. + */ + boolean BitBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HDC hdcSrc, int nXSrc, int nYSrc, + int dwRop); + } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/GDI32Util.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/GDI32Util.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/GDI32Util.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/GDI32Util.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,195 @@ +/* Copyright (c) 2015 Michael Freeman, 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 java.awt.Rectangle; +import java.awt.image.BufferedImage; +import java.awt.image.DataBuffer; +import java.awt.image.DataBufferInt; +import java.awt.image.DirectColorModel; +import java.awt.image.Raster; +import java.awt.image.WritableRaster; + +import com.sun.jna.Memory; +import com.sun.jna.Native; +import com.sun.jna.platform.win32.GDI32; +import com.sun.jna.platform.win32.User32; +import com.sun.jna.platform.win32.Win32Exception; +import com.sun.jna.platform.win32.WinDef.HBITMAP; +import com.sun.jna.platform.win32.WinDef.HDC; +import com.sun.jna.platform.win32.WinDef.HWND; +import com.sun.jna.platform.win32.WinDef.RECT; +import com.sun.jna.platform.win32.WinError; +import com.sun.jna.platform.win32.WinGDI; +import com.sun.jna.platform.win32.WinGDI.BITMAPINFO; +import com.sun.jna.platform.win32.WinNT.HANDLE; + +/** + * GDI32 utility API. + * + * @author mlfreeman[at]gmail.com + */ +public class GDI32Util { + private static final DirectColorModel SCREENSHOT_COLOR_MODEL = new DirectColorModel(24, 0x00FF0000, 0xFF00, 0xFF); + private static final int[] SCREENSHOT_BAND_MASKS = { + SCREENSHOT_COLOR_MODEL.getRedMask(), + SCREENSHOT_COLOR_MODEL.getGreenMask(), + SCREENSHOT_COLOR_MODEL.getBlueMask() + }; + + /** + * Takes a screenshot of the given window + * + * @param target + * The window to target + * @return the window captured as a screenshot, or null if the BufferedImage doesn't construct properly + * @throws IllegalStateException + * if the rectangle from GetWindowRect has a width and/or height + * of 0.
    + * if the device context acquired from the original HWND doesn't + * release properly + */ + public static BufferedImage getScreenshot(HWND target) { + RECT rect = new RECT(); + if (!User32.INSTANCE.GetWindowRect(target, rect)) { + throw new Win32Exception(Native.getLastError()); + } + Rectangle jRectangle = rect.toRectangle(); + int windowWidth = jRectangle.width; + int windowHeight = jRectangle.height; + + if (windowWidth == 0 || windowHeight == 0) { + throw new IllegalStateException("Window width and/or height were 0 even though GetWindowRect did not appear to fail."); + } + + HDC hdcTarget = User32.INSTANCE.GetDC(target); + if (hdcTarget == null) { + throw new Win32Exception(Native.getLastError()); + } + + Win32Exception we = null; + + // device context used for drawing + HDC hdcTargetMem = null; + + // handle to the bitmap to be drawn to + HBITMAP hBitmap = null; + + // original display surface associated with the device context + HANDLE hOriginal = null; + + // final java image structure we're returning. + BufferedImage image = null; + + try { + hdcTargetMem = GDI32.INSTANCE.CreateCompatibleDC(hdcTarget); + if (hdcTargetMem == null) { + throw new Win32Exception(Native.getLastError()); + } + + hBitmap = GDI32.INSTANCE.CreateCompatibleBitmap(hdcTarget, windowWidth, windowHeight); + if (hBitmap == null) { + throw new Win32Exception(Native.getLastError()); + } + + hOriginal = GDI32.INSTANCE.SelectObject(hdcTargetMem, hBitmap); + if (hOriginal == null) { + throw new Win32Exception(Native.getLastError()); + } + + // draw to the bitmap + if (!GDI32.INSTANCE.BitBlt(hdcTargetMem, 0, 0, windowWidth, windowHeight, hdcTarget, 0, 0, GDI32.SRCCOPY)) { + throw new Win32Exception(Native.getLastError()); + } + + BITMAPINFO bmi = new BITMAPINFO(); + bmi.bmiHeader.biWidth = windowWidth; + bmi.bmiHeader.biHeight = -windowHeight; + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = 32; + bmi.bmiHeader.biCompression = WinGDI.BI_RGB; + + Memory buffer = new Memory(windowWidth * windowHeight * 4); + int resultOfDrawing = GDI32.INSTANCE.GetDIBits(hdcTarget, hBitmap, 0, windowHeight, buffer, bmi, + WinGDI.DIB_RGB_COLORS); + if (resultOfDrawing == 0 || resultOfDrawing == WinError.ERROR_INVALID_PARAMETER) { + throw new Win32Exception(Native.getLastError()); + } + + int bufferSize = windowWidth * windowHeight; + DataBuffer dataBuffer = new DataBufferInt(buffer.getIntArray(0, bufferSize), bufferSize); + WritableRaster raster = Raster.createPackedRaster(dataBuffer, windowWidth, windowHeight, windowWidth, + SCREENSHOT_BAND_MASKS, null); + image = new BufferedImage(SCREENSHOT_COLOR_MODEL, raster, false, null); + + } catch (Win32Exception e) { + we = e; + } finally { + if (hOriginal != null) { + // per MSDN, set the display surface back when done drawing + HANDLE result = GDI32.INSTANCE.SelectObject(hdcTargetMem, hOriginal); + // failure modes are null or equal to HGDI_ERROR + if (result == null || WinGDI.HGDI_ERROR.equals(result)) { + Win32Exception ex = new Win32Exception(Native.getLastError()); + if (we != null) { + ex.addSuppressed(we); + } + we = ex; + } + } + + if (hBitmap != null) { + if (!GDI32.INSTANCE.DeleteObject(hBitmap)) { + Win32Exception ex = new Win32Exception(Native.getLastError()); + if (we != null) { + ex.addSuppressed(we); + } + we = ex; + } + } + + if (hdcTargetMem != null) { + // get rid of the device context when done + if (!GDI32.INSTANCE.DeleteDC(hdcTargetMem)) { + Win32Exception ex = new Win32Exception(Native.getLastError()); + if (we != null) { + ex.addSuppressed(we); + } + we = ex; + } + } + + if (hdcTarget != null) { + if (0 == User32.INSTANCE.ReleaseDC(target, hdcTarget)) { + throw new IllegalStateException("Device context did not release properly."); + } + } + } + + if (we != null) { + throw we; + } + return image; + } +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/GL.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/GL.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/GL.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/GL.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,23 +1,32 @@ /* Copyright (c) 2011 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.win32.StdCallLibrary; - /** * Definitions for WinOpenGL */ -public interface GL extends StdCallLibrary { +public interface GL { public final int GL_VENDOR = 0x1F00; public final int GL_RENDERER = 0x1F01; public final int GL_VERSION = 0x1F02; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Guid.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Guid.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Guid.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Guid.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2010 Daniel Doubrovkine, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; @@ -17,12 +28,12 @@ import java.util.List; import com.sun.jna.Pointer; +import com.sun.jna.PointerType; import com.sun.jna.Structure; -// TODO: Auto-generated Javadoc /** * Ported from Guid.h. Microsoft Windows SDK 6.0A. - * + * * @author dblock[at]dblock.org */ public interface Guid { @@ -38,7 +49,9 @@ public static class GUID extends Structure { public static class ByValue extends GUID implements Structure.ByValue { - public ByValue() {} + public ByValue() { + super(); + } public ByValue(GUID guid) { super(guid.getPointer()); @@ -51,24 +64,24 @@ super(memory); } } - + /** * The Class ByReference. * * @author Tobias Wolf, wolf.tobias@gmx.net */ - public static class ByReference extends GUID implements - Structure.ByReference { + public static class ByReference extends GUID implements Structure.ByReference { /** * Instantiates a new by reference. */ public ByReference() { + super(); } /** * Instantiates a new by reference. - * + * * @param guid * the guid */ @@ -83,7 +96,7 @@ /** * Instantiates a new by reference. - * + * * @param memory * the memory */ @@ -92,6 +105,8 @@ } } + public static final List FIELDS = createFieldsOrder("Data1", "Data2", "Data3", "Data4"); + /** The Data1. */ public int Data1; @@ -108,13 +123,13 @@ * Instantiates a new guid. */ public GUID() { + super(); } /** * Instantiates a new guid. - * - * @param guid - * the guid + * + * @param guid the guid */ public GUID(GUID guid) { this.Data1 = guid.Data1; @@ -127,7 +142,7 @@ /** * Instantiates a new guid. - * + * * @param guid * the guid */ @@ -137,7 +152,7 @@ /** * Instantiates a new guid. - * + * * @param data * the data */ @@ -147,7 +162,7 @@ /** * Instantiates a new guid. - * + * * @param memory * the memory */ @@ -156,9 +171,33 @@ read(); } + @Override + public boolean equals(Object o) { + if (o == null) { + return false; + } + if (this == o) { + return true; + } + if (getClass() != o.getClass()) { + return false; + } + + GUID other = (GUID) o; + return (this.Data1 == other.Data1) + && (this.Data2 == other.Data2) + && (this.Data3 == other.Data3) + && Arrays.equals(this.Data4, other.Data4); + } + + @Override + public int hashCode() { + return this.Data1 + this.Data2 & 0xFFFF + this.Data3 & 0xFFFF + Arrays.hashCode(this.Data4); + } + /** * From binary. - * + * * @param data * the data * @return the guid @@ -205,7 +244,7 @@ /** * From string. - * + * * @param guid * the guid * @return the guid @@ -277,7 +316,7 @@ /** * Generates a new guid. Code taken from the standard jdk implementation * (see UUID class). - * + * * @return the guid */ public static GUID newGuid() { @@ -295,7 +334,7 @@ /** * To byte array. - * + * * @return the byte[] */ public byte[] toByteArray() { @@ -330,7 +369,7 @@ /** * The value of this Guid, formatted as follows: * xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx. - * + * * @return the string */ public String toGuidString() { @@ -357,20 +396,14 @@ * Write fields to backing memory. */ protected void writeFieldsToMemory() { - this.writeField("Data1"); - this.writeField("Data2"); - this.writeField("Data3"); - this.writeField("Data4"); + for (String name : FIELDS) { + this.writeField(name); + } } - /* - * (non-Javadoc) - * - * @see com.sun.jna.Structure#getFieldOrder() - */ - protected List getFieldOrder() { - return Arrays.asList(new String[] { "Data1", "Data2", "Data3", - "Data4" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } @@ -392,26 +425,27 @@ * Instantiates a new by reference. */ public ByReference() { + super(); } /** * Instantiates a new by reference. - * + * * @param guid * the guid */ public ByReference(GUID guid) { super(guid); } - + /** * Instantiates a new by reference. - * + * * @param memory * the memory */ public ByReference(Pointer memory) { - + super(memory); } } @@ -419,8 +453,9 @@ * Instantiates a new clsid. */ public CLSID() { + super(); } - + /** * Instantiates a new clsid. * @@ -429,7 +464,7 @@ public CLSID(String guid) { super(guid); } - + /** * Instantiates a new clsid. * @@ -441,43 +476,76 @@ } /** - * The Class REFIID. - * - * @author Tobias Wolf, wolf.tobias@gmx.net + * REFIID is a pointer to an IID. + * + * This type needs to be seperate from IID, as the REFIID can be passed in + * from external code, that does not allow writes to memory. + * + * With the normal JNA behaviour a structure, that crosses the native<->Java + * border will be autowritten, which causes a fault when written. + * Observed was this behaviour in COM-Callbacks, which get the REFIID passed + * into Invoke-method. + * + * So a IID can't be used directly, although the typedef of REFIID (from MSDN): + * + * typedef IID* REFIID; + * + * and the jna behaviour is described as: + * + * "When a function requires a pointer to a struct, a Java Structure should be used." */ - public class REFIID extends IID { + public class REFIID extends PointerType { /** * Instantiates a new refiid. */ public REFIID() { - // TODO Auto-generated constructor stub } /** * Instantiates a new refiid. - * + * * @param memory * the memory */ public REFIID(Pointer memory) { super(memory); - // TODO Auto-generated constructor stub } - /** - * Instantiates a new refiid. - * - * @param data - * the data - */ - public REFIID(byte[] data) { - super(data); - // TODO Auto-generated constructor stub + public REFIID(IID guid) { + super(guid.getPointer()); + } + + public void setValue(IID value) { + setPointer(value.getPointer()); } - } + public IID getValue() { + return new IID(getPointer()); + } + + @Override + public boolean equals(Object o) { + if (o == null) { + return false; + } + if (this == o) { + return true; + } + if (getClass() != o.getClass()) { + return false; + } + + REFIID other = (REFIID) o; + return getValue().equals(other.getValue()); + } + @Override + public int hashCode() { + return getValue().hashCode(); + } + } + /** * The Class IID. * @@ -489,18 +557,17 @@ * Instantiates a new iid. */ public IID() { - // TODO Auto-generated constructor stub + super(); } /** * Instantiates a new iid. - * + * * @param memory * the memory */ public IID(Pointer memory) { super(memory); - // TODO Auto-generated constructor stub } /** @@ -510,18 +577,21 @@ */ public IID(String iid) { super(iid); - // TODO Auto-generated constructor stub } /** * Instantiates a new iid. - * + * * @param data * the data */ public IID(byte[] data) { super(data); - // TODO Auto-generated constructor stub } + + public IID(GUID guid) { + this(guid.toGuidString()); + } + } } \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/HighLevelMonitorConfigurationAPI.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/HighLevelMonitorConfigurationAPI.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/HighLevelMonitorConfigurationAPI.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/HighLevelMonitorConfigurationAPI.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,17 +1,26 @@ /* * Copyright 2014 Martin Steiger * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * 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; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,22 +1,34 @@ /* Copyright (c) 2007, 2013 Timothy Wall, Markus Karg, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

    - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.LastErrorException; import com.sun.jna.Native; import com.sun.jna.Pointer; -import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.ptr.IntByReference; import com.sun.jna.ptr.PointerByReference; +import com.sun.jna.win32.StdCallLibrary; import com.sun.jna.win32.W32APIOptions; /** @@ -24,11 +36,35 @@ * alternate mappings from {@link WinNT} which make use of NIO buffers, * {@link Wincon} for console API. */ -public interface Kernel32 extends WinNT, Wincon { +public interface Kernel32 extends StdCallLibrary, WinNT, Wincon { /** The instance. */ - Kernel32 INSTANCE = (Kernel32) Native.loadLibrary("kernel32", - Kernel32.class, W32APIOptions.UNICODE_OPTIONS); + Kernel32 INSTANCE = Native.loadLibrary("kernel32", Kernel32.class, W32APIOptions.DEFAULT_OPTIONS); + + /** + * LOAD_LIBRARY_AS_DATAFILE
    + * 0x00000002
    + * If this value is used, the system maps the file into the calling + * process's virtual address space as if it were a data file.
    + * Nothing is done to execute or prepare to execute the mapped file.
    + * Therefore, you cannot call functions like + * GetModuleFileName + * , + * GetModuleHandle + * or + * GetProcAddress + * with this DLL. Using this value causes writes to read-only memory to + * raise an access violation.
    + * Use this flag when you want to load a DLL only to extract messages or + * resources from it.
    + * This value can be used with + * LOAD_LIBRARY_AS_IMAGE_RESOURCE. For more information, + * see Remarks. + */ + int LOAD_LIBRARY_AS_DATAFILE = 0x2; /** * Reads data from the specified file or input/output (I/O) device. Reads @@ -70,14 +106,16 @@ /** * Frees the specified local memory object and invalidates its handle. * - * @param hLocal - * A handle to the local memory object. + * @param hMem + * A handle to the local memory object. If the hMem parameter + * is NULL, {@code LocalFree} ignores the parameter and returns NULL. * @return If the function succeeds, the return value is NULL. If the * function fails, the return value is equal to a handle to the * local memory object. To get extended error information, call - * GetLastError. + * {@code GetLastError}. + * @see LocalFree */ - Pointer LocalFree(Pointer hLocal); + Pointer LocalFree(Pointer hMem); /** * Frees the specified global memory object and invalidates its handle. @@ -87,7 +125,8 @@ * @return If the function succeeds, the return value is NULL If the * function fails, the return value is equal to a handle to the * global memory object. To get extended error information, call - * GetLastError. + * {@code GetLastError}. + * @see GlobalFree */ Pointer GlobalFree(Pointer hGlobal); @@ -156,6 +195,32 @@ boolean SetLocalTime(SYSTEMTIME lpSystemTime); /** + * Retrieves system timing information. On a multiprocessor system, the + * values returned are the sum of the designated times across all + * processors. + * + * @param lpIdleTime + * A pointer to a {@link WinBase.FILETIME} structure that + * receives the amount of time that the system has been idle. + * @param lpKernelTime + * A pointer to a {@link WinBase.FILETIME} structure that + * receives the amount of time that the system has spent + * executing in Kernel mode (including all threads in all + * processes, on all processors). This time value also includes + * the amount of time the system has been idle. + * @param lpUserTime + * A pointer to a {@link WinBase.FILETIME} structure that + * receives the amount of time that the system has spent + * executing in User mode (including all threads in all + * processes, on all processors). + * @return {@code true} if the function succeeds, {@code false} otherwise. + * If the function fails, call {@link #GetLastError()} to get extended error + * information. + * @see GetSystemTimes documentation + */ + boolean GetSystemTimes(WinBase.FILETIME lpIdleTime, WinBase.FILETIME lpKernelTime, WinBase.FILETIME lpUserTime); + + /** * The GetTickCount function retrieves the number of milliseconds that have * elapsed since the system was started, up to 49.7 days. * @@ -165,6 +230,15 @@ int GetTickCount(); /** + * The GetTickCount64 function retrieves the number of milliseconds that + * have elapsed since the system was started. + * + * @return Number of milliseconds that have elapsed since the system was + * started. + */ + long GetTickCount64(); + + /** * The GetCurrentThreadId function retrieves the thread identifier of the * calling thread. * @@ -682,14 +756,15 @@ int dwDesiredAccess, boolean bInheritHandle, int dwOptions); /** - * The CloseHandle function closes an open object handle. + * Closes an open object handle. * * @param hObject * Handle to an open object. This parameter can be a pseudo * handle or INVALID_HANDLE_VALUE. * @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. + * information, call {@code GetLastError}. + * @see CloseHandle */ boolean CloseHandle(HANDLE hObject); @@ -1201,10 +1276,16 @@ /** * This function returns a handle to an existing process object. * - * @param fdwAccess - * Not supported; set to zero. - * @param fInherit - * Not supported; set to FALSE. + * @param fdwAccess The access to the process object. This access right is + * checked against the security descriptor for the process. This parameter + * can be one or more of the process access rights. + *

    + * If the caller has enabled the SeDebugPrivilege privilege, the requested + * access is granted regardless of the contents of the security + * descriptor.

    + * + * @param fInherit If this value is TRUE, processes created by this process will inherit the handle. Otherwise, the processes do not inherit this handle. + * * @param IDProcess * Specifies the process identifier of the process to open. * @return An open handle to the specified process indicates success. NULL @@ -1214,6 +1295,26 @@ HANDLE OpenProcess(int fdwAccess, boolean fInherit, int IDProcess); /** + * This function retrieves the full path of the executable file of a given process. + * + * @param hProcess + * Handle for the running process + * @param dwFlags + * 0 - The name should use the Win32 path format. + * 1(WinNT.PROCESS_NAME_NATIVE) - The name should use the native system path format. + * @param lpExeName + * pre-allocated character buffer for the returned path + * @param lpdwSize + * input: the size of the allocated buffer + * output: the length of the returned path in characters + * + * @return true if successful false if not. To get extended error information, + * call GetLastError. + */ + boolean QueryFullProcessImageName(HANDLE hProcess, int dwFlags, char[] lpExeName, IntByReference lpdwSize); + + + /** * The GetTempPath function retrieves the path of the directory designated * for temporary files. * @@ -1343,6 +1444,48 @@ boolean GlobalMemoryStatusEx(MEMORYSTATUSEX lpBuffer); /** + * Retrieves file information for the specified file. + * To set file information using a file handle, see SetFileInformationByHandle. + * @param hFile + * A handle to the file that contains the information to be retrieved. + * @param FileInformationClass + * A FILE_INFO_BY_HANDLE_CLASS enumeration value that specifies the type of + * information to be retrieved. + * @param lpFileInformation + * A pointer to the buffer that receives the requested file information. + * The structure that is returned corresponds to the class that is specified + * by FileInformationClass. + * @param dwBufferSize + * The size of the lpFileInformation buffer, in bytes. + * @return If the function succeeds, the return value is nonzero and file information + * data is contained in the buffer pointed to by the lpFileInformation parameter. + * If the function fails, the return value is zero. To get extended error + * information, call GetLastError. + */ + boolean GetFileInformationByHandleEx(HANDLE hFile, int FileInformationClass, Pointer lpFileInformation, DWORD dwBufferSize); + + /** + * Sets the file information for the specified file. To retrieve file information using a + * file handle, see GetFileInformationByHandleEx. + * @param hFile + * A handle to the file for which to change information. + * This handle must be opened with the appropriate permissions for the + * requested change. This handle should not be a pipe handle. + * @param FileInformationClass + * A FILE_INFO_BY_HANDLE_CLASS enumeration value that specifies the type of information to be changed. + * Valid values are FILE_BASIC_INFO, FILE_RENAME_INFO, FILE_DISPOSITION_INFO, FILE_ALLOCATION_INFO, + * FILE_END_OF_FILE_INFO, and FILE_IO_PRIORITY_HINT_INFO + * @param lpFileInformation + * A pointer to the buffer that contains the information to change for the specified file + * information class. The structure that this parameter points to corresponds to the class + * that is specified by FileInformationClass. + * @param dwBufferSize + * The size of the lpFileInformation buffer, in bytes. + * @return Returns nonzero if successful or zero otherwise. To get extended error information, call GetLastError. + */ + boolean SetFileInformationByHandle(HANDLE hFile, int FileInformationClass, Pointer lpFileInformation, DWORD dwBufferSize); + + /** * Retrieves the date and time that a file or directory was created, last * accessed, and last modified. * @@ -2394,6 +2537,18 @@ boolean SystemTimeToFileTime(SYSTEMTIME lpSystemTime, FILETIME lpFileTime); /** + * Converts a file time to system time format. System time is based on Coordinated Universal Time (UTC). + * @param lpFileTime + * [in] A pointer to a FILETIME structure containing the file time to be converted to system (UTC) date and time format. + This value must be less than 0x8000000000000000. Otherwise, the function fails. + * @param lpSystemTime + * A pointer to a SYSTEMTIME structure to receive the converted file time. + * @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. + */ + boolean FileTimeToSystemTime(FILETIME lpFileTime, SYSTEMTIME lpSystemTime); + + /** * Creates a thread that runs in the virtual address space of another process. * * @param hProcess A handle to the process in which the thread is to be created. @@ -2437,17 +2592,32 @@ /** * Reads data from an area of memory in a specified process. The entire area * to be read must be accessible or the operation fails. - * @param hProcess A handle to the process with memory that is being read. - * @param lpBaseAddress The base address in the specified process from which - * to read. - * @param lpBuffer A buffer that receives the contents from the address space - * of the specified process. - * @param nSize The number of bytes to be read from the specified process. - * @param lpNumberOfBytesRead A variable that receives the number of bytes - * transferred into the specified buffer. If {@code null} the parameter is ignored. - * @return {@code true} if successful, {@code false} otherwise. - * To get extended error information, call {@link #GetLastError()}. - * @see ReadProcessMemory documentation + * + * @see MSDN + * @param hProcess + * A handle to the process with memory that is being read. The + * handle must have PROCESS_VM_READ access to the process. + * @param lpBaseAddress + * A pointer to the base address in the specified process from + * which to read.
    + * Before any data transfer occurs, the system verifies that all + * data in the base address and memory of the specified size is + * accessible for read access, and if it is not accessible the + * function fails. + * @param lpBuffer + * A pointer to a buffer that receives the contents from the + * address space of the specified process. + * @param nSize + * The number of bytes to be read from the specified process. + * @param lpNumberOfBytesRead + * A pointer to a variable that receives the number of bytes + * transferred into the specified buffer. If lpNumberOfBytesRead + * is NULL, the parameter is ignored. + * @return If the function succeeds, the return value is nonzero.
    + * If the function fails, the return value is 0 (zero). To get + * extended error information, call GetLastError.
    + * The function fails if the requested read operation crosses into + * an area of the process that is inaccessible. */ boolean ReadProcessMemory(HANDLE hProcess, Pointer lpBaseAddress, Pointer lpBuffer, int nSize, IntByReference lpNumberOfBytesRead); @@ -2512,6 +2682,100 @@ int QueryDosDevice(String lpDeviceName, char[] lpTargetPath, int ucchMax); /** + * Searches a directory for a file or subdirectory with a name that matches a specific name (or partial name if wildcards are used). + * To specify additional attributes to use in a search, use the FindFirstFileEx function. + * @param lpFileName + * The directory or path, and the file name. The file name can include wildcard characters, + * for example, an asterisk (*) or a question mark (?). + * This parameter should not be NULL, an invalid string (for example, an empty string or a string that is + * missing the terminating null character), or end in a trailing backslash (\). + * If the string ends with a wildcard, period, or directory name, the user must have access to the root + * and all subdirectories on the path. + * In the ANSI version of this function, the name is limited to MAX_PATH characters. To extend this + * limit to approximately 32,000 wide characters, call the Unicode version of the function (FindFirstFileExW), + * and prepend "\\?\" to the path. For more information, see Naming a File. + * Tip Starting in Windows 10, version 1607, for the unicode version of this function (FindFirstFileExW), + * you can opt-in to remove the MAX_PATH character limitation without prepending "\\?\". + * See the "Maximum Path Limitation" section of Naming Files, Paths, and Namespaces for details. + * @param lpFindFileData + * A pointer to the buffer that receives the file data. The pointer type is determined by the level of + * information that is specified in the fInfoLevelId parameter. + * @return If the function succeeds, the return value is a search handle used in a subsequent call to FindNextFile or FindClose, + * and the lpFindFileData parameter contains information about the first file or directory found. + * If the function fails or fails to locate files from the search string in the lpFileName parameter, the return + * value is INVALID_HANDLE_VALUE and the contents of lpFindFileData are indeterminate. + * To get extended error information, call the GetLastError function. + * If the function fails because no matching files can be found, the GetLastError function returns ERROR_FILE_NOT_FOUND. + */ + HANDLE FindFirstFile(String lpFileName, Pointer lpFindFileData); + + /** + * Searches a directory for a file or subdirectory with a name and attributes that match those specified. For the most basic + * version of this function, see FindFirstFile. + * @param lpFileName + * The directory or path, and the file name. The file name can include wildcard characters, + * for example, an asterisk (*) or a question mark (?). + * This parameter should not be NULL, an invalid string (for example, an empty string or a string that is + * missing the terminating null character), or end in a trailing backslash (\). + * If the string ends with a wildcard, period, or directory name, the user must have access to the root + * and all subdirectories on the path. + * In the ANSI version of this function, the name is limited to MAX_PATH characters. To extend this + * limit to approximately 32,000 wide characters, call the Unicode version of the function (FindFirstFileExW), + * and prepend "\\?\" to the path. For more information, see Naming a File. + * Tip Starting in Windows 10, version 1607, for the unicode version of this function (FindFirstFileExW), + * you can opt-in to remove the MAX_PATH character limitation without prepending "\\?\". + * See the "Maximum Path Limitation" section of Naming Files, Paths, and Namespaces for details. + * @param fInfoLevelId + * The information level of the returned data. This parameter is one of the FINDEX_INFO_LEVELS enumeration values. + * @param lpFindFileData + * A pointer to the buffer that receives the file data. The pointer type is determined by the level of + * information that is specified in the fInfoLevelId parameter. + * @param fSearchOp + * The type of filtering to perform that is different from wildcard matching. This parameter is one of + * the FINDEX_SEARCH_OPS enumeration values. + * @param lpSearchFilter + * A pointer to the search criteria if the specified fSearchOp needs structured search information. + * At this time, none of the supported fSearchOp values require extended search information. Therefore, + * this pointer must be NULL. + * @param dwAdditionalFlags + * Specifies additional flags that control the search. + * FIND_FIRST_EX_CASE_SENSITIVE (0x01) - Searches are case-sensitive. + * FIND_FIRST_EX_LARGE_FETCH (0x02) - Uses a larger buffer for directory queries, which can increase performance + * of the find operation. Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This value + * is not supported until Windows Server 2008 R2 and Windows 7. + * @return If the function succeeds, the return value is a search handle used in a subsequent call to FindNextFile or FindClose, + * and the lpFindFileData parameter contains information about the first file or directory found. + * If the function fails or fails to locate files from the search string in the lpFileName parameter, the return + * value is INVALID_HANDLE_VALUE and the contents of lpFindFileData are indeterminate. + * To get extended error information, call the GetLastError function. + * If the function fails because no matching files can be found, the GetLastError function returns ERROR_FILE_NOT_FOUND. + */ + HANDLE FindFirstFileEx(String lpFileName, int fInfoLevelId, Pointer lpFindFileData, int fSearchOp, Pointer lpSearchFilter, DWORD dwAdditionalFlags); + + /** + * Continues a file search from a previous call to the FindFirstFile, FindFirstFileEx, or FindFirstFileTransacted functions. + * @param hFindFile + * The search handle returned by a previous call to the FindFirstFile or FindFirstFileEx function. + * @param lpFindFileData + * A pointer to the WIN32_FIND_DATA structure that receives information about the found file or subdirectory. + * @return If the function succeeds, the return value is nonzero and the lpFindFileData parameter contains + * information about the next file or directory found. If the function fails, the return value is zero and the + * contents of lpFindFileData are indeterminate. To get extended error information, call the GetLastError function. + * If the function fails because no more matching files can be found, the GetLastError function returns ERROR_NO_MORE_FILES. + */ + boolean FindNextFile(HANDLE hFindFile, Pointer lpFindFileData); + + /** + * Closes a file search handle opened by the FindFirstFile, FindFirstFileEx, FindFirstFileNameW, FindFirstFileNameTransactedW, + * FindFirstFileTransacted, FindFirstStreamTransactedW, or FindFirstStreamW functions. + * @param hFindFile + * The file search handle. + * @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. + */ + boolean FindClose(HANDLE hFindFile); + + /** * Retrieves the name of a mounted folder on the specified volume - used * to begin scanning the mounted folders on a volume * @param lpszRootPathName A volume GUID path for the volume to scan for @@ -2730,87 +2994,567 @@ * @see FindVolumeClose */ boolean FindVolumeClose(HANDLE hFindVolume); + + /** + * Retrieves the current control settings for a specified communications + * device. + * + * @param hFile + * [in] A handle to the communications device.
    + * The + * {@link com.sun.jna.platform.win32.Kernel32#CreateFile(String, int, int, com.sun.jna.platform.win32.WinBase.SECURITY_ATTRIBUTES, int, int, com.sun.jna.platform.win32.WinNT.HANDLE)} + * function returns this {@link WinNT.HANDLE}. + * @param lpDCB + * [in, out] A pointer to a {@link WinBase.DCB} structure that + * receives the control settings information. + * + * @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 {@link Kernel32#GetLastError()}. + * + */ + boolean GetCommState(HANDLE hFile, WinBase.DCB lpDCB); + + /** + * + * Retrieves the time-out parameters for all read and write operations on a + * specified communications device.
    + *
    + * For more information about time-out values for communications devices, + * see the {@link Kernel32#SetCommTimeouts} function. + * + * @param hFile + * [in] A handle to the communications device. The + * {@link com.sun.jna.platform.win32.Kernel32#CreateFile(String, int, int, com.sun.jna.platform.win32.WinBase.SECURITY_ATTRIBUTES, int, int, com.sun.jna.platform.win32.WinNT.HANDLE)} + * function returns this handle. + * + * @param lpCommTimeouts + * [in] A pointer to a {@link WinBase.COMMTIMEOUTS} structure in + * which the time-out information is returned. + * @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 {@link Kernel32#GetLastError()}. + * + * + * + */ + boolean GetCommTimeouts(HANDLE hFile, WinBase.COMMTIMEOUTS lpCommTimeouts); + + /** + * Configures a communications device according to the specifications in a + * device-control block (a {@link WinBase.DCB} structure). The function + * reinitializes all hardware and control settings, but it does not empty + * output or input queues. + * + * @param hFile + * [in] A handle to the communications device. The + * {@link com.sun.jna.platform.win32.Kernel32#CreateFile(String, int, int, com.sun.jna.platform.win32.WinBase.SECURITY_ATTRIBUTES, int, int, com.sun.jna.platform.win32.WinNT.HANDLE)} + * function returns this handle. + * @param lpDCB + * [in] A pointer to a {@link WinBase.DCB} structure that + * contains the configuration information for the specified + * communications device. + * @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 {@link Kernel32#GetLastError()}. + */ + boolean SetCommState(HANDLE hFile, WinBase.DCB lpDCB); + + /** + * Sets the time-out parameters for all read and write operations on a + * specified communications device. + * + * @param hFile + * [in] A handle to the communications device. The + * {@link com.sun.jna.platform.win32.Kernel32#CreateFile(String, int, int, com.sun.jna.platform.win32.WinBase.SECURITY_ATTRIBUTES, int, int, com.sun.jna.platform.win32.WinNT.HANDLE)} + * function returns this handle. + * @param lpCommTimeouts + * [in] A pointer to a {@link WinBase.COMMTIMEOUTS} structure + * that contains the new time-out values. + * @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 {@link Kernel32#GetLastError()}. + */ + boolean SetCommTimeouts(HANDLE hFile, WinBase.COMMTIMEOUTS lpCommTimeouts); + + /** + * http://msdn.microsoft.com/en-us/library/aa382990(v=vs.85).aspx
    + *
    + * Retrieves the Remote Desktop Services session associated with a specified + * process.
    + *
    + *
    BOOL ProcessIdToSessionId(_In_ DWORD dwProcessId, _Out_ DWORD *pSessionId);

    + * + * @param dwProcessId + * Specifies a process identifier.
    + * Use the GetCurrentProcessId function to retrieve the process + * identifier for the current process. + * @param pSessionId + * Pointer to a variable that receives the identifier of the + * Remote Desktop Services session under which the specified + * process is running.
    + * To retrieve the identifier of the session currently attached + * to the console, use the WTSGetActiveConsoleSessionId function. + * @return If the function succeeds, the return value is true.
    + * If the function fails, the return value is false. To get extended + * error information, call GetLastError. + */ + boolean ProcessIdToSessionId(int dwProcessId, IntByReference pSessionId); + + /** + * Loads the specified module into the address space of the calling process. + * The specified module may cause other modules to be loaded. + * + *
    +     * 
    +     * HMODULE WINAPI LoadLibraryEx(
    +     *   _In_       LPCTSTR lpFileName,
    +     *   _Reserved_ HANDLE  hFile,
    +     *   _In_       DWORD   dwFlags
    +     * );
    +     * 
    +     * 
    + * + * @param lpFileName + * A string that specifies the file name of the module to load. + * This name is not related to the name stored in a library + * module itself, as specified by the LIBRARY keyword in the + * module-definition (.def) file.
    + * The module can be a library module (a .dll file) or an + * executable module (an .exe file). If the specified module is + * an executable module, static imports are not loaded; instead, + * the module is loaded as if DONT_RESOLVE_DLL_REFERENCES was + * specified. See the dwFlags parameter for more + * information.
    + * If the string specifies a module name without a path and the + * file name extension is omitted, the function appends the + * default library extension .dll to the module name. To prevent + * the function from appending .dll to the module name, include a + * trailing point character (.) in the module name string.
    + * If the string specifies a fully qualified path, the function + * searches only that path for the module. When specifying a + * path, be sure to use backslashes (\), not forward slashes (/). + * For more information about paths, see "Naming Files, Paths, and Namespaces" on MSDN.
    + * If the string specifies a module name without a path and more + * than one loaded module has the same base name and extension, + * the function returns a handle to the module that was loaded + * first.
    + * If the string specifies a module name without a path and a + * module of the same name is not already loaded, or if the + * string specifies a module name with a relative path, the + * function searches for the specified module. The function also + * searches for modules if loading the specified module causes + * the system to load other associated modules (that is, if the + * module has dependencies). The directories that are searched + * and the order in which they are searched depend on the + * specified path and the dwFlags parameter. For more + * information, see Remarks.
    + * If the function cannot find the module or one of its + * dependencies, the function fails. + * @param hFile + * This parameter is reserved for future use. It must be NULL. + * @param flags + * The action to be taken when loading the module.
    + * If no flags are specified, the behavior of this function is + * identical to that of the LoadLibrary function.
    + * This parameter can be one of the following values.
    + *
    + * DONT_RESOLVE_DLL_REFERENCES: 0x00000001
    + * If this value is used, and the executable module is a DLL, the + * system does not call DllMain for process and thread + * initialization and termination. Also, the system does not load + * additional executable modules that are referenced by the + * specified module.
    + * Do not use this value; it is provided only for backward + * compatibility. If you are planning to access only data or + * resources in the DLL, use LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE + * or LOAD_LIBRARY_AS_IMAGE_RESOURCE or both. Otherwise, load the + * library as a DLL or executable module using the LoadLibrary + * function.
    + *
    + * LOAD_IGNORE_CODE_AUTHZ_LEVEL: 0x00000010
    + * If this value is used, the system does not check AppLocker + * rules or apply Software Restriction Policies for the DLL. + * AppLocker was introduced in Windows 7 and Windows Server 2008 + * R2. This action applies only to the DLL being loaded and not + * to its dependencies. This value is recommended for use in + * setup programs that must run extracted DLLs during + * installation.
    + * Windows Server 2008 R2 and Windows 7: On systems with + * KB2532445 installed, the caller must be running as + * "LocalSystem" or "TrustedInstaller"; otherwise the system + * ignores this flag.
    + *
    + * LOAD_LIBRARY_AS_DATAFILE: 0x00000002
    + * If this value is used, the system maps the file into the + * calling process's virtual address space as if it were a data + * file. Nothing is done to execute or prepare to execute the + * mapped file. Therefore, you cannot call functions like + * GetModuleFileName, GetModuleHandle or GetProcAddress with this + * DLL. Using this value causes writes to read-only memory to + * raise an access violation. Use this flag when you want to load + * a DLL only to extract messages or resources from it.
    + * This value can be used with LOAD_LIBRARY_AS_IMAGE_RESOURCE. + * For more information, see Remarks
    + *
    + * LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE: 0x00000040
    + * Similar to LOAD_LIBRARY_AS_DATAFILE, except that the DLL file + * is opened with exclusive write access for the calling process. + * Other processes cannot open the DLL file for write access + * while it is in use. However, the DLL can still be opened by + * other processes.
    + * This value can be used with LOAD_LIBRARY_AS_IMAGE_RESOURCE. + * This value is not supported until Windows Vista.
    + *
    + * LOAD_LIBRARY_AS_IMAGE_RESOURCE: 0x00000020
    + * If this value is used, the system maps the file into the + * process's virtual address space as an image file. However, the + * loader does not load the static imports or perform the other + * usual initialization steps. Use this flag when you want to + * load a DLL only to extract messages or resources from it.
    + * Unless the application depends on the file having the + * in-memory layout of an image, this value should be used with + * either LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE or + * LOAD_LIBRARY_AS_DATAFILE. This value is not supported until + * Windows Vista.
    + *
    + * LOAD_LIBRARY_SEARCH_APPLICATION_DIR: 0x00000200
    + * If this value is used, the application's installation + * directory is searched for the DLL and its dependencies. + * Directories in the standard search path are not searched. This + * value cannot be combined with LOAD_WITH_ALTERED_SEARCH_PATH. + *
    + * Windows 7, Windows Server 2008 R2, Windows Vista, and Windows + * Server 2008: This value requires KB2533623 to be installed. + *
    + *
    + * LOAD_LIBRARY_SEARCH_DEFAULT_DIRS: 0x00001000
    + * This value is a combination of + * LOAD_LIBRARY_SEARCH_APPLICATION_DIR, + * LOAD_LIBRARY_SEARCH_SYSTEM32, and + * LOAD_LIBRARY_SEARCH_USER_DIRS. Directories in the standard + * search path are not searched. This value cannot be combined + * with LOAD_WITH_ALTERED_SEARCH_PATH.
    + * This value represents the recommended maximum number of + * directories an application should include in its DLL search + * path.
    + * Windows 7, Windows Server 2008 R2, Windows Vista, and Windows + * Server 2008: This value requires KB2533623 to be installed. + *
    + *
    + * LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR: 0x00000100
    + * + * If this value is used, the directory that contains the DLL is + * temporarily added to the beginning of the list of directories + * that are searched for the DLL's dependencies. Directories in + * the standard search path are not searched.
    + * The lpFileName parameter must specify a fully qualified path. + * This value cannot be combined with + * LOAD_WITH_ALTERED_SEARCH_PATH.
    + * For example, if Lib2.dll is a dependency of C:\Dir1\Lib1.dll, + * loading Lib1.dll with this value causes the system to search + * for Lib2.dll only in C:\Dir1. To search for Lib2.dll in + * C:\Dir1 and all of the directories in the DLL search path, + * combine this value with LOAD_LIBRARY_DEFAULT_DIRS.
    + * Windows 7, Windows Server 2008 R2, Windows Vista, and Windows + * Server 2008: This value requires KB2533623 to be installed. + *
    + *
    + * LOAD_LIBRARY_SEARCH_SYSTEM32: 0x00000800
    + * If this value is used, %windows%\system32 is searched for the + * DLL and its dependencies. Directories in the standard search + * path are not searched. This value cannot be combined with + * LOAD_WITH_ALTERED_SEARCH_PATH.
    + * Windows 7, Windows Server 2008 R2, Windows Vista, and Windows + * Server 2008: This value requires KB2533623 to be installed. + *
    + *
    + * LOAD_LIBRARY_SEARCH_USER_DIRS: 0x00000400
    + * If this value is used, directories added using the + * AddDllDirectory or the SetDllDirectory function are searched + * for the DLL and its dependencies. If more than one directory + * has been added, the order in which the directories are + * searched is unspecified. Directories in the standard search + * path are not searched. This value cannot be combined with + * LOAD_WITH_ALTERED_SEARCH_PATH.
    + * Windows 7, Windows Server 2008 R2, Windows Vista, and Windows + * Server 2008: This value requires KB2533623 to be installed. + *
    + *
    + * LOAD_WITH_ALTERED_SEARCH_PATH: 0x00000008
    + * If this value is used and lpFileName specifies an + * absolute path, the system uses the alternate file search + * strategy discussed in the Remarks section to find associated + * executable modules that the specified module causes to be + * loaded. If this value is used and lpFileName + * specifies a relative path, the behavior is undefined.
    + * If this value is not used, or if lpFileName does not + * specify a path, the system uses the standard search strategy + * discussed in the Remarks section to find associated executable + * modules that the specified module causes to be loaded.
    + * This value cannot be combined with any LOAD_LIBRARY_SEARCH + * flag. + * @return If the function succeeds, the return value is a handle to the + * loaded module.
    + * If the function fails, the return value is NULL. To get extended + * error information, call GetLastError. + */ + HMODULE LoadLibraryEx(String lpFileName, HANDLE hFile, int flags); + + /** + * Determines the location of a resource with the specified type and name in + * the specified module.
    + * To specify a language, use the FindResourceEx function. + * + * @param hModule + * A handle to the module whose portable executable file or an + * accompanying MUI file contains the resource.
    + * If this parameter is NULL, the function searches the module + * used to create the current process. + * @param name + * The name of the resource.
    + * Alternately, rather than a pointer, this parameter can be + * MAKEINTRESOURCE(ID), where ID is the integer identifier of the + * resource.
    + * For more information, see the Remarks section below. + * @param type + * The resource type.
    + * Alternately, rather than a pointer, this parameter can be + * MAKEINTRESOURCE(ID), where ID is the integer identifier of the + * given resource type.
    + * For standard resource types, see Resource Types. For more + * information, see the Remarks section below. + * @return If the function succeeds, the return value is a handle to the + * specified resource's information block.
    + * To obtain a handle to the resource, pass this handle to the + * LoadResource function.
    + * If the function fails, the return value is NULL.
    + * To get extended error information, call GetLastError. + */ + HRSRC FindResource(HMODULE hModule, Pointer name, Pointer type); + + /** + * Retrieves a handle that can be used to obtain a pointer to the first byte + * of the specified resource in memory. + * + * @param hModule + * A handle to the module whose executable file contains the + * resource.
    + * If hModule is NULL, the system loads the resource from the + * module that was used to create the current process. + * @param hResource + * A handle to the resource to be loaded.
    + * This handle is returned by the FindResource or FindResourceEx + * function. + * @return If the function succeeds, the return value is a handle to the + * data associated with the resource.
    + * If the function fails, the return value is NULL.
    + * To get extended error information, call GetLastError. + */ + HANDLE LoadResource(HMODULE hModule, HRSRC hResource); + + /** + * Retrieves a pointer to the specified resource in memory. + * + * @param hResource + * A handle to the resource to be accessed.
    + * The LoadResource function returns this handle.
    + * Note that this parameter is listed as an HGLOBAL variable only + * for backward compatibility.
    + * Do not pass any value as a parameter other than a successful + * return value from the LoadResource function. + * @return If the loaded resource is available, the return value is a + * pointer to the first byte of the resource; otherwise, it is NULL. + */ + Pointer LockResource(HANDLE hResource); + + /** + * @param hModule + * A handle to the module whose executable file contains the + * resource. + * @param hResource + * A handle to the resource. This handle must be created by using + * the FindResource or FindResourceEx function. + * @return If the function succeeds, the return value is the number of bytes + * in the resource.
    + * If the function fails, the return value is zero. To get extended + * error information, call GetLastError. + */ + int SizeofResource(HMODULE hModule, HANDLE hResource); + + + /** + * Frees the loaded dynamic-link library (DLL) module and, if necessary, + * decrements its reference count. When the reference count reaches zero, + * the module is unloaded from the address space of the calling process and + * the handle is no longer valid. + * + * @param module + * A handle to the loaded library module. The LoadLibrary, + * LoadLibraryEx, GetModuleHandle, or GetModuleHandleEx function + * returns this handle. + * @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 the GetLastError function. + */ + boolean FreeLibrary(HMODULE module); + + /** + * Enumerates resource types within a binary module.
    + * Starting with Windows Vista, this is typically a language-neutral + * Portable Executable (LN file), and the enumeration also includes + * resources from one of the corresponding language-specific resource files + * (.mui files)-if one exists-that contain localizable language resources. + * It is also possible to use hModule to specify a .mui file, in which case + * only that file is searched for resource types.
    + * Alternately, applications can call EnumResourceTypesEx, which provides + * more precise control over which resource files to enumerate. + * + * @param hModule + * A handle to a module to be searched.
    + * This handle must be obtained through LoadLibrary or + * LoadLibraryEx.
    + * See Remarks for more information. If this parameter is NULL, + * that is equivalent to passing in a handle to the module used + * to create the current process. + * @param proc + * A pointer to the callback function to be called for each + * enumerated resource type.
    + * For more information, see the EnumResTypeProc function. + * @param lParam + * An application-defined value passed to the callback function. + * @return Returns TRUE if successful; otherwise, FALSE. To get extended + * error information, call GetLastError. + */ + boolean EnumResourceTypes(HMODULE hModule, WinBase.EnumResTypeProc proc, Pointer lParam); + + /** + * Enumerates resources of a specified type within a binary module.
    + * For Windows Vista and later, this is typically a language-neutral + * Portable Executable (LN file), and the enumeration will also include + * resources from the corresponding language-specific resource files (.mui + * files) that contain localizable language resources.
    + * It is also possible for hModule to specify an .mui file, in which case + * only that file is searched for resources. + * + * @param hModule + * A handle to a module to be searched.
    + * Starting with Windows Vista, if this is an LN file, then + * appropriate .mui files (if any exist) are included in the + * search.
    + * If this parameter is NULL, that is equivalent to passing in a + * handle to the module used to create the current process. + * @param type + * The type of the resource for which the name is being + * enumerated.
    + * Alternately, rather than a pointer, this parameter can be + * MAKEINTRESOURCE(ID), where ID is an integer value representing + * a predefined resource type.
    + * For a list of predefined resource types, see Resource Types. + * For more information, see the Remarks section below. + * @param proc + * A pointer to the callback function to be called for each + * enumerated resource name or ID. For more information, see + * EnumResNameProc. + * @param lParam + * An application-defined value passed to the callback function. + * This parameter can be used in error checking. + * @return The return value is TRUE if the function succeeds or FALSE if the + * function does not find a resource of the type specified, or if + * the function fails for another reason. To get extended error + * information, call GetLastError. + */ + boolean EnumResourceNames(HMODULE hModule, Pointer type, WinBase.EnumResNameProc proc, Pointer lParam); + + /** + * Retrieves information about the first module associated with a process. + * + * @see MSDN + * @param hSnapshot + * A handle to the snapshot returned from a previous call to the + * CreateToolhelp32Snapshot function. + * @param lpme + * A pointer to a MODULEENTRY32 structure. + * @return Returns TRUE if the first entry of the module list has been + * copied to the buffer or FALSE otherwise.
    + * The ERROR_NO_MORE_FILES error value is returned by the + * GetLastError function if no modules exist or the snapshot does + * not contain module information. + */ + boolean Module32FirstW(HANDLE hSnapshot, Tlhelp32.MODULEENTRY32W lpme); + + /** + * Retrieves information about the next module associated with a process or + * thread. + * + * @see MSDN + * @param hSnapshot + * A handle to the snapshot returned from a previous call to the + * CreateToolhelp32Snapshot function. + * @param lpme + * A pointer to a MODULEENTRY32 structure. + * @return Returns TRUE if the first entry of the module list has been + * copied to the buffer or FALSE otherwise.
    + * The ERROR_NO_MORE_FILES error value is returned by the + * GetLastError function if no modules exist or the snapshot does + * not contain module information. + */ + boolean Module32NextW(HANDLE hSnapshot, Tlhelp32.MODULEENTRY32W lpme); /** - * Retrieves the current control settings for a specified communications - * device. - * - * @param hFile - * [in] A handle to the communications device.
    - * The - * {@link com.sun.jna.platform.win32.Kernel32#CreateFile(String, int, int, com.sun.jna.platform.win32.WinBase.SECURITY_ATTRIBUTES, int, int, com.sun.jna.platform.win32.WinNT.HANDLE)} - * function returns this {@link HANDLE}. - * @param lpDCB - * [in, out] A pointer to a {@link WinBase.DCB} structure that - * receives the control settings information. - * - * @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 {@link Kernel32#GetLastError()}. - * - */ - boolean GetCommState(HANDLE hFile, WinBase.DCB lpDCB); - - /** - * - * Retrieves the time-out parameters for all read and write operations on a - * specified communications device.
    - *
    - * For more information about time-out values for communications devices, - * see the {@link Kernel32#SetCommTimeouts} function. - * - * @param hFile - * [in] A handle to the communications device. The - * {@link com.sun.jna.platform.win32.Kernel32#CreateFile(String, int, int, com.sun.jna.platform.win32.WinBase.SECURITY_ATTRIBUTES, int, int, com.sun.jna.platform.win32.WinNT.HANDLE)} - * function returns this handle. - * - * @param lpCommTimeouts - * [in] A pointer to a {@link WinBase.COMMTIMEOUTS} structure in - * which the time-out information is returned. - * @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 {@link Kernel32#GetLastError()}. - * - * - * - */ - boolean GetCommTimeouts(HANDLE hFile, WinBase.COMMTIMEOUTS lpCommTimeouts); - - /** - * Configures a communications device according to the specifications in a - * device-control block (a {@link WinBase.DCB} structure). The function - * reinitializes all hardware and control settings, but it does not empty - * output or input queues. - * - * @param hFile - * [in] A handle to the communications device. The - * {@link com.sun.jna.platform.win32.Kernel32#CreateFile(String, int, int, com.sun.jna.platform.win32.WinBase.SECURITY_ATTRIBUTES, int, int, com.sun.jna.platform.win32.WinNT.HANDLE)} - * function returns this handle. - * @param lpDCB - * [in] A pointer to a {@link WinBase.DCB} structure that - * contains the configuration information for the specified - * communications device. - * @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 {@link Kernel32#GetLastError()}. - */ - boolean SetCommState(HANDLE hFile, WinBase.DCB lpDCB); - - /** - * Sets the time-out parameters for all read and write operations on a - * specified communications device. - * - * @param hFile - * [in] A handle to the communications device. The - * {@link com.sun.jna.platform.win32.Kernel32#CreateFile(String, int, int, com.sun.jna.platform.win32.WinBase.SECURITY_ATTRIBUTES, int, int, com.sun.jna.platform.win32.WinNT.HANDLE)} - * function returns this handle. - * @param LPCOMMTIMEOUTS - * [in] A pointer to a {@link WinBase.COMMTIMEOUTS} structure - * that contains the new time-out values. - * @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 {@link Kernel32#GetLastError()}. - */ - boolean SetCommTimeouts(HANDLE hFile, WinBase.COMMTIMEOUTS lpCommTimeouts); + * Controls whether the system will handle the specified types of serious + * errors or whether the process will handle them. + * @see MSDN + * + * @param umode + * The process error mode. + * @return The return value is the previous state of the error-mode bit + * flags. + */ + int SetErrorMode(int umode); + + /** + * Retrieves the address of an exported function or variable from the + * specified dynamic-link library (DLL). + * + *

    + * This function is mapped to enable accessing function on win32 systems + * only accessible by their ordinal value.

    + * + *

    + * To access functions by their name, please use + * NativeLibrary#getFunction.

    + * + * @param hmodule A handle to the DLL module that contains the function or + * variable. The LoadLibrary, LoadLibraryEx, + * LoadPackagedLibrary, or GetModuleHandle function returns + * this handle. + * @param ordinal ordinal value of the function export + * @return address of the exported function + */ + Pointer GetProcAddress(HMODULE hmodule, int ordinal) throws LastErrorException; + + /** + * Enables an application to inform the system that it is in use, thereby + * preventing the system from entering sleep or turning off the display + * while the application is running. + * + * @param esFlags The thread's execution requirements. This parameter can be + * one or more of the following values (ORed together) + * + *
      + *
    • {@link com.sun.jna.platform.win32.WinBase#ES_AWAYMODE_REQUIRED}
    • + *
    • {@link com.sun.jna.platform.win32.WinBase#ES_CONTINUOUS}
    • + *
    • {@link com.sun.jna.platform.win32.WinBase#ES_DISPLAY_REQUIRED}
    • + *
    • {@link com.sun.jna.platform.win32.WinBase#ES_SYSTEM_REQUIRED}
    • + *
    • {@link com.sun.jna.platform.win32.WinBase#ES_USER_PRESENT}
    • + *
    + * + * @return If the function succeeds, the return value is the previous thread + * execution state. + *

    + * If the function fails, the return value is 0

    + */ + int SetThreadExecutionState(int esFlags); } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,20 +1,33 @@ /* Copyright (c) 2010, 2013 Daniel Doubrovkine, Markus Karg, 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * You can freely decide which license you want to apply to + * the project. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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 java.io.File; import java.io.FileNotFoundException; import java.nio.ByteOrder; +import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.TreeMap; @@ -31,7 +44,7 @@ /** * Kernel32 utility API. - * + * * @author dblock[at]dblock.org * @author markus[at]headcrashing[dot]eu * @author Andreas "PAX" Lück, onkelpax-git[at]yahoo.de @@ -40,7 +53,7 @@ /** * Get current computer NetBIOS name. - * + * * @return Netbios name. */ public static String getComputerName() { @@ -53,32 +66,148 @@ } /** + * Invokes {@link Kernel32#LocalFree(Pointer)} and checks if it succeeded. + * + * @param ptr The {@link Pointer} to the memory to be released - ignored if NULL + * @throws Win32Exception if non-{@code ERROR_SUCCESS} code reported + */ + public static void freeLocalMemory(Pointer ptr) { + Pointer res = Kernel32.INSTANCE.LocalFree(ptr); + if (res != null) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + } + + /** + * Invokes {@link Kernel32#GlobalFree(Pointer)} and checks if it succeeded. + * + * @param ptr The {@link Pointer} to the memory to be released - ignored if NULL + * @throws Win32Exception if non-{@code ERROR_SUCCESS} code reported + */ + public static void freeGlobalMemory(Pointer ptr) { + Pointer res = Kernel32.INSTANCE.GlobalFree(ptr); + if (res != null) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + } + + /** + * Closes all referenced handles. If an exception is thrown for + * a specific handle, then it is accumulated until all + * handles have been closed. If more than one exception occurs, + * then it is added as a suppressed exception to the first one. + * Once closed all handles, the accumulated exception (if any) is thrown + * + * @param refs The references to close + * @see #closeHandleRef(WinNT.HANDLEByReference) + */ + public static void closeHandleRefs(HANDLEByReference... refs) { + Win32Exception err = null; + for (HANDLEByReference r : refs) { + try { + closeHandleRef(r); + } catch(Win32Exception e) { + if (err == null) { + err = e; + } else { + err.addSuppressed(e); + } + } + } + + if (err != null) { + throw err; + } + } + /** + * Closes the handle in the reference + * + * @param ref The handle reference - ignored if {@code null} + * @see #closeHandle(WinNT.HANDLE) + */ + public static void closeHandleRef(HANDLEByReference ref) { + closeHandle((ref == null) ? null : ref.getValue()); + } + + /** + * Invokes {@link #closeHandle(WinNT.HANDLE)} on each handle. If an exception + * is thrown for a specific handle, then it is accumulated until all + * handles have been closed. If more than one exception occurs, then it + * is added as a suppressed exception to the first one. Once closed all + * handles, the accumulated exception (if any) is thrown + * + * @param handles The handles to be closed + * @see Throwable#getSuppressed() + */ + public static void closeHandles(HANDLE... handles) { + Win32Exception err = null; + for (HANDLE h : handles) { + try { + closeHandle(h); + } catch(Win32Exception e) { + if (err == null) { + err = e; + } else { + err.addSuppressed(e); + } + } + } + + if (err != null) { + throw err; + } + } + + /** + * Invokes {@link Kernel32#CloseHandle(WinNT.HANDLE)} and checks the success code. + * If not successful, then throws a {@link Win32Exception} with the + * {@code GetLastError} value + * + * @param h The handle to be closed - ignored if {@code null} + */ + public static void closeHandle(HANDLE h) { + if (h == null) { + return; + } + + if (!Kernel32.INSTANCE.CloseHandle(h)) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + } + + /** * Format a message from the value obtained from - * {@link Kernel32#GetLastError} or {@link Native#getLastError}. - * - * @param code - * int + * {@link Kernel32#GetLastError()} or {@link Native#getLastError()}. + * + * @param code The error code * @return Formatted message. */ public static String formatMessage(int code) { PointerByReference buffer = new PointerByReference(); - if (0 == Kernel32.INSTANCE.FormatMessage( + int nLen = Kernel32.INSTANCE.FormatMessage( WinBase.FORMAT_MESSAGE_ALLOCATE_BUFFER - | WinBase.FORMAT_MESSAGE_FROM_SYSTEM - | WinBase.FORMAT_MESSAGE_IGNORE_INSERTS, null, code, 0, // TODO: - // MAKELANGID(LANG_NEUTRAL, - // SUBLANG_DEFAULT) - buffer, 0, null)) { - throw new LastErrorException(Kernel32.INSTANCE.GetLastError()); + | WinBase.FORMAT_MESSAGE_FROM_SYSTEM + | WinBase.FORMAT_MESSAGE_IGNORE_INSERTS, + null, + code, + 0, // TODO: // MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT) + buffer, 0, null); + if (nLen == 0) { + throw new LastErrorException(Native.getLastError()); + } + + Pointer ptr = buffer.getValue(); + try { + String s = ptr.getWideString(0); + return s.trim(); + } finally { + freeLocalMemory(ptr); } - String s = buffer.getValue().getWideString(0); - Kernel32.INSTANCE.LocalFree(buffer.getValue()); - return s.trim(); } /** * Format a message from an HRESULT. - * + * * @param code * HRESULT * @return Formatted message. @@ -92,13 +221,14 @@ * @param code error code * @return formatted message */ + @Deprecated public static String formatMessageFromHR(HRESULT code) { return formatMessage(code.intValue()); } /** * Format a system message from an error code. - * + * * @param code * Error code, typically a result of GetLastError. * @return Formatted message. @@ -107,18 +237,18 @@ return formatMessageFromHR(W32Errors.HRESULT_FROM_WIN32(code)); } - /** - * @return Obtains the human-readable error message text from the last error - * that occurred by invocating {@code Kernel32.GetLastError()}. - */ - public static String getLastErrorMessage() { - return Kernel32Util.formatMessageFromLastErrorCode(Kernel32.INSTANCE - .GetLastError()); - } + /** + * @return Obtains the human-readable error message text from the last error + * that occurred by invocating {@code Kernel32.GetLastError()}. + */ + public static String getLastErrorMessage() { + return Kernel32Util.formatMessageFromLastErrorCode(Kernel32.INSTANCE + .GetLastError()); + } /** * Return the path designated for temporary files. - * + * * @return Path. */ public static String getTempPath() { @@ -138,7 +268,7 @@ /** * Returns valid drives in the system. - * + * * @return A {@link List} of valid drives. */ public static List getLogicalDriveStrings() { @@ -159,7 +289,7 @@ /** * Retrieves file system attributes for a specified file or directory. - * + * * @param fileName * The name of the file or directory. * @return The attributes of the specified file or directory. @@ -185,6 +315,7 @@ } HANDLE hFile = null; + Win32Exception err = null; try { hFile = Kernel32.INSTANCE.CreateFile(fileName, WinNT.GENERIC_READ, WinNT.FILE_SHARE_READ, new WinBase.SECURITY_ATTRIBUTES(), @@ -197,25 +328,36 @@ int type = Kernel32.INSTANCE.GetFileType(hFile); switch (type) { - case WinNT.FILE_TYPE_UNKNOWN: - int err = Kernel32.INSTANCE.GetLastError(); - switch (err) { - case WinError.NO_ERROR: - break; - default: - throw new Win32Exception(err); - } + case WinNT.FILE_TYPE_UNKNOWN: + int rc = Kernel32.INSTANCE.GetLastError(); + switch (rc) { + case WinError.NO_ERROR: + break; + default: + throw new Win32Exception(rc); + } // fall-thru default: return type; } + } catch(Win32Exception e) { + err = e; + throw err; // re-throw so finally block executed } finally { - if (hFile != null) { - if (!Kernel32.INSTANCE.CloseHandle(hFile)) { - throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + try { + closeHandle(hFile); + } catch(Win32Exception e) { + if (err == null) { + err = e; + } else { + err.addSuppressed(e); } } + + if (err != null) { + throw err; + } } } @@ -229,7 +371,7 @@ /** * Get the value of an environment variable. - * + * * @param name * Name of the environment variable. * @return Value of an environment variable. @@ -265,7 +407,7 @@ if (lpszEnvironmentBlock == null) { throw new LastErrorException(Kernel32.INSTANCE.GetLastError()); } - + try { return getEnvironmentVariables(lpszEnvironmentBlock, 0L); } finally { @@ -284,7 +426,7 @@ * Note: if the environment block is {@code null} then {@code null} * is returned instead of an empty map since we want to distinguish * between the case that the data block is {@code null} and when there are - * no environment variables (as unlikely as it may be) + * no environment variables (as unlikely as it may be) */ public static Map getEnvironmentVariables(Pointer lpszEnvironmentBlock, long offset) { if (lpszEnvironmentBlock == null) { @@ -305,13 +447,13 @@ if (pos < 0) { throw new IllegalArgumentException("Missing variable value separator in " + nvp); } - + String name=nvp.substring(0, pos), value=nvp.substring(pos + 1); vars.put(name, value); curOffset += (len + 1 /* skip the ending '\0' */) * stepFactor; } - + return vars; } @@ -333,7 +475,7 @@ if (dataLen == 0) { return ""; } - + int charsLen=asWideChars ? (dataLen / 2) : dataLen; char[] chars=new char[charsLen]; long curOffset=offset, stepSize=asWideChars ? 2L : 1L; @@ -351,7 +493,7 @@ chars[index] = (char) (b & 0x00FF); } } - + return new String(chars); } @@ -388,10 +530,10 @@ * the assumption is that the environment variable name (at * least) is ASCII. * - * + * *
  • * Otherwise (i.e., zero charset indicator), it is assumed to be - * a {@code wchar_t} + * a {@code wchar_t} *
  • * * Note: the code takes into account the {@link ByteOrder} even though @@ -413,7 +555,7 @@ return isWideCharEnvironmentStringBlock(b0); } } - + private static boolean isWideCharEnvironmentStringBlock(byte charsetIndicator) { // assume wchar_t for environment variables represents ASCII letters if (charsetIndicator != 0) { @@ -426,7 +568,7 @@ /** * Retrieves an integer associated with a key in the specified section of an * initialization file. - * + * * @param appName * The name of the section in the initialization file. * @param keyName @@ -451,7 +593,7 @@ /** * Retrieves a string from the specified section in an initialization file. - * + * * @param lpAppName * The name of the section containing the key name. If this * parameter is {@code null}, the @@ -516,7 +658,7 @@ /** * Convenience method to get the processor information. Takes care of * auto-growing the array. - * + * * @return the array of processor information. */ public static final WinNT.SYSTEM_LOGICAL_PROCESSOR_INFORMATION[] getLogicalProcessorInformation() { @@ -543,7 +685,7 @@ return (WinNT.SYSTEM_LOGICAL_PROCESSOR_INFORMATION[]) firstInformation .toArray(new WinNT.SYSTEM_LOGICAL_PROCESSOR_INFORMATION[returnedStructCount]); } - + /** * Retrieves all the keys and values for the specified section of an initialization file. * @@ -639,7 +781,7 @@ if (hr != WinError.ERROR_MORE_DATA) { throw new Win32Exception(hr); } - + int required = lpcchReturnLength.getValue(); lpszVolumePathNames = new char[required]; // this time we MUST succeed @@ -647,7 +789,7 @@ throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); } } - + int bufSize = lpcchReturnLength.getValue(); return Native.toStringList(lpszVolumePathNames, 0, bufSize); } @@ -660,7 +802,7 @@ * Parses and returns the pure GUID value of a volume name obtained * from {@link Kernel32#FindFirstVolume(char[], int)} or * {@link Kernel32#FindNextVolume} calls - * + * * @param volumeGUIDPath * The volume GUID path as returned by one of the above mentioned calls * @return The pure GUID value after stripping the "\\?\" prefix and @@ -675,7 +817,281 @@ || (!volumeGUIDPath.endsWith(VOLUME_GUID_PATH_SUFFIX))) { throw new IllegalArgumentException("Bad volume GUID path format: " + volumeGUIDPath); } - + return volumeGUIDPath.substring(VOLUME_GUID_PATH_PREFIX.length(), volumeGUIDPath.length() - VOLUME_GUID_PATH_SUFFIX.length()); } + + /** + * + * This function retrieves the full path of the executable file of a given process. + * + * @param hProcess + * Handle for the running process + * @param dwFlags + * 0 - The name should use the Win32 path format. + * 1(WinNT.PROCESS_NAME_NATIVE) - The name should use the native system path format. + * + * @return the full path of the process's executable file of null if failed. To get extended error information, + * call GetLastError. + */ + public static final String QueryFullProcessImageName(HANDLE hProcess, int dwFlags) { + char[] path = new char[WinDef.MAX_PATH]; + IntByReference lpdwSize = new IntByReference(path.length); + if (Kernel32.INSTANCE.QueryFullProcessImageName(hProcess, 0, path, lpdwSize)) + return new String(path).substring(0, lpdwSize.getValue()); + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + /** + * Gets the specified resource out of the specified executable file + * + * @param path + * The path to the executable file + * @param type + * The type of the resource (either a type name or type ID is + * allowed) + * @param name + * The name or ID of the resource + * @return The resource bytes, or null if no such resource exists. + * @throws IllegalStateException if the call to LockResource fails + */ + public static byte[] getResource(String path, String type, String name) { + HMODULE target = Kernel32.INSTANCE.LoadLibraryEx(path, null, Kernel32.LOAD_LIBRARY_AS_DATAFILE); + + if (target == null) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + Win32Exception err = null; + Pointer start = null; + int length = 0; + byte[] results = null; + try { + Pointer t = null; + try { + t = new Pointer(Long.parseLong(type)); + } catch (NumberFormatException e) { + t = new Memory(Native.WCHAR_SIZE * (type.length() + 1)); + t.setWideString(0, type); + } + + Pointer n = null; + try { + n = new Pointer(Long.parseLong(name)); + } catch (NumberFormatException e) { + n = new Memory(Native.WCHAR_SIZE * (name.length() + 1)); + n.setWideString(0, name); + } + + HRSRC hrsrc = Kernel32.INSTANCE.FindResource(target, n, t); + if (hrsrc == null) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + // according to MSDN, on 32 bit Windows or newer, calling FreeResource() is not necessary - and in fact does nothing but return false. + HANDLE loaded = Kernel32.INSTANCE.LoadResource(target, hrsrc); + if (loaded == null) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + length = Kernel32.INSTANCE.SizeofResource(target, hrsrc); + if (length == 0) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + // MSDN: It is not necessary to unlock resources because the system automatically deletes them when the process that created them terminates. + // MSDN does not say that LockResource sets GetLastError + start = Kernel32.INSTANCE.LockResource(loaded); + if (start == null) { + throw new IllegalStateException("LockResource returned null."); + } + // have to capture it into a byte array before you free the library, otherwise bad things happen. + results = start.getByteArray(0, length); + } catch (Win32Exception we) { + err = we; + } finally { + // from what I can tell on MSDN, the only thing that needs cleanup on this is the HMODULE from LoadLibrary + if (target != null) { + if (!Kernel32.INSTANCE.FreeLibrary(target)) { + Win32Exception we = new Win32Exception(Kernel32.INSTANCE.GetLastError()); + if (err != null) { + we.addSuppressed(err); + } + throw we; + } + } + } + + if (err != null) { + throw err; + } + + return results; + } + + /** + * Gets a list of all resources from the specified executable file + * + * @param path + * The path to the executable file + * @return A map of resource type name/ID => resources.
    + * A map key + a single list item + the path to the executable can + * be handed off to getResource() to actually get the resource. + */ + public static Map> getResourceNames(String path) { + HMODULE target = Kernel32.INSTANCE.LoadLibraryEx(path, null, Kernel32.LOAD_LIBRARY_AS_DATAFILE); + + if (target == null) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + final List types = new ArrayList(); + final Map> result = new LinkedHashMap>(); + + WinBase.EnumResTypeProc ertp = new WinBase.EnumResTypeProc() { + + @Override + public boolean invoke(HMODULE module, Pointer type, Pointer lParam) { + // simulate IS_INTRESOURCE macro defined in WinUser.h + // basically that means that if "type" is less than or equal to 65,535 + // it assumes it's an ID. + // otherwise it assumes it's a pointer to a string + if (Pointer.nativeValue(type) <= 65535) { + types.add(Pointer.nativeValue(type) + ""); + } else { + types.add(type.getWideString(0)); + } + return true; + } + }; + + WinBase.EnumResNameProc ernp = new WinBase.EnumResNameProc() { + + @Override + public boolean invoke(HMODULE module, Pointer type, Pointer name, Pointer lParam) { + String typeName = ""; + + if (Pointer.nativeValue(type) <= 65535) { + typeName = Pointer.nativeValue(type) + ""; + } else { + typeName = type.getWideString(0); + } + + if (Pointer.nativeValue(name) < 65535) { + result.get(typeName).add(Pointer.nativeValue(name) + ""); + } else { + result.get(typeName).add(name.getWideString(0)); + } + + return true; + } + }; + + + Win32Exception err = null; + try { + if (!Kernel32.INSTANCE.EnumResourceTypes(target, ertp, null)) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + for (final String typeName : types) { + result.put(typeName, new ArrayList()); + + // simulate MAKEINTRESOURCE macro in WinUser.h + // basically, if the value passed in can be parsed as a number then convert it into one and run with that. + // otherwise, assume it's a string and construct a pointer to said string. + Pointer pointer = null; + try { + pointer = new Pointer(Long.parseLong(typeName)); + } catch (NumberFormatException e) { + pointer = new Memory(Native.WCHAR_SIZE * (typeName.length() + 1)); + pointer.setWideString(0, typeName); + } + + boolean callResult = Kernel32.INSTANCE.EnumResourceNames(target, pointer, ernp, null); + + if (!callResult) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + } + } catch (Win32Exception e) { + err = e; + } finally { + // from what I can tell on MSDN, the only thing that needs cleanup + // on this is the HMODULE from LoadLibrary + if (target != null) { + if (!Kernel32.INSTANCE.FreeLibrary(target)) { + Win32Exception we = new Win32Exception(Kernel32.INSTANCE.GetLastError()); + if (err != null) { + we.addSuppressed(err); + } + throw we; + } + } + } + + if (err != null) { + throw err; + } + return result; + } + + /** + * Returns all the executable modules for a given process ID.
    + * + * @param processID + * The process ID to get executable modules for + * @return All the modules in the process. + */ + public static List getModules(int processID) { + HANDLE snapshot = Kernel32.INSTANCE.CreateToolhelp32Snapshot(Tlhelp32.TH32CS_SNAPMODULE, new DWORD(processID)); + if (snapshot == null) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + Win32Exception we = null; + try { + Tlhelp32.MODULEENTRY32W first = new Tlhelp32.MODULEENTRY32W(); + + if (!Kernel32.INSTANCE.Module32FirstW(snapshot, first)) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + List modules = new ArrayList(); + modules.add(first); + + Tlhelp32.MODULEENTRY32W next = new Tlhelp32.MODULEENTRY32W(); + while (Kernel32.INSTANCE.Module32NextW(snapshot, next)) { + modules.add(next); + next = new Tlhelp32.MODULEENTRY32W(); + } + + int lastError = Kernel32.INSTANCE.GetLastError(); + // if we got a false from Module32Next, + // check to see if it returned false because we're genuinely done + // or if something went wrong. + if (lastError != W32Errors.ERROR_SUCCESS && lastError != W32Errors.ERROR_NO_MORE_FILES) { + throw new Win32Exception(lastError); + } + + return modules; + } catch (Win32Exception e) { + we = e; + throw we; // re-throw so finally block is executed + } finally { + try { + closeHandle(snapshot); + } catch(Win32Exception e) { + if (we == null) { + we = e; + } else { + we.addSuppressed(e); + } + } + + if (we != null) { + throw we; + } + } + } } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/KnownFolders.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/KnownFolders.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/KnownFolders.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/KnownFolders.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,3 +1,25 @@ +/* + * 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.platform.win32.Guid.GUID; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/LMAccess.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/LMAccess.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/LMAccess.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/LMAccess.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,199 +1,217 @@ /* 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * You can freely decide which license you want to apply to + * the project. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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 java.util.Arrays; import java.util.List; import com.sun.jna.Pointer; import com.sun.jna.Structure; -import com.sun.jna.WString; import com.sun.jna.platform.win32.WinNT.PSID; -import com.sun.jna.win32.StdCallLibrary; +import com.sun.jna.win32.W32APITypeMapper; /** * Ported from LMAccess.h. * Windows SDK 6.0A. * @author dblock[at]dblock.org */ -public interface LMAccess extends StdCallLibrary { - +public interface LMAccess { + public static class LOCALGROUP_INFO_0 extends Structure { + public static final List FIELDS = createFieldsOrder("lgrui0_name"); + + public String lgrui0_name; + public LOCALGROUP_INFO_0() { - super(); + super(W32APITypeMapper.UNICODE); } - + public LOCALGROUP_INFO_0(Pointer memory) { - super(memory); + super(memory, Structure.ALIGN_DEFAULT, W32APITypeMapper.UNICODE); read(); } - - public WString lgrui0_name; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "lgrui0_name" }); + + @Override + protected List getFieldOrder() { + return FIELDS; } } public static class LOCALGROUP_INFO_1 extends Structure { + public static final List FIELDS = createFieldsOrder("lgrui1_name", "lgrui1_comment"); + + public String lgrui1_name; + public String lgrui1_comment; + public LOCALGROUP_INFO_1() { - super(); + super(W32APITypeMapper.UNICODE); } public LOCALGROUP_INFO_1(Pointer memory) { - super(memory); + super(memory, Structure.ALIGN_DEFAULT, W32APITypeMapper.UNICODE); read(); } - public WString lgrui1_name; - public WString lgrui1_comment; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "lgrui1_name", "lgrui1_comment" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } - + // // bit masks for the NetUserEnum filter parameter. // - + int FILTER_TEMP_DUPLICATE_ACCOUNT = 0x0001; int FILTER_NORMAL_ACCOUNT = 0x0002; // int FILTER_PROXY_ACCOUNT = 0x0004; int FILTER_INTERDOMAIN_TRUST_ACCOUNT = 0x0008; int FILTER_WORKSTATION_TRUST_ACCOUNT = 0x0010; - int FILTER_SERVER_TRUST_ACCOUNT = 0x0020; - + int FILTER_SERVER_TRUST_ACCOUNT = 0x0020; + /** * The USER_INFO_0 structure contains a user account name. */ public static class USER_INFO_0 extends Structure { + public static final List FIELDS = createFieldsOrder("usri0_name"); + /** + * Pointer to a Unicode string that specifies the name of the user account. + */ + public String usri0_name; + public USER_INFO_0() { - super(); + super(W32APITypeMapper.UNICODE); } public USER_INFO_0(Pointer memory) { - super(memory); + super(memory, Structure.ALIGN_DEFAULT, W32APITypeMapper.UNICODE); read(); } - /** - * Pointer to a Unicode string that specifies the name of the user account. - */ - public WString usri0_name; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "usri0_name" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } - + /** - * The USER_INFO_1 structure contains information about a user account, including - * account name, password data, privilege level, and the path to the user's home + * The USER_INFO_1 structure contains information about a user account, including + * account name, password data, privilege level, and the path to the user's home * directory. */ public static class USER_INFO_1 extends Structure { - public USER_INFO_1() { - super(); - } - - public USER_INFO_1(Pointer memory) { - super(memory); - read(); - } + public static final List FIELDS = createFieldsOrder( + "usri1_name", "usri1_password", "usri1_password_age", "usri1_priv", + "usri1_home_dir", "usri1_comment", "usri1_flags", "usri1_script_path"); /** - * Pointer to a Unicode string that specifies the name of the user + * Pointer to a Unicode string that specifies the name of the user * account. */ - public WString usri1_name; + public String usri1_name; /** * Pointer to a Unicode string that specifies the password of the user - * indicated by the usri1_name member. + * indicated by the usri1_name member. */ - public WString usri1_password; + public String usri1_password; /** - * Specifies a DWORD value that indicates the number of seconds that have + * Specifies a DWORD value that indicates the number of seconds that have * elapsed since the usri1_password member was last changed. */ public int usri1_password_age; /** - * Specifies a DWORD value that indicates the level of privilege assigned + * Specifies a DWORD value that indicates the level of privilege assigned * to the usri1_name member. */ public int usri1_priv; /** - * Pointer to a Unicode string specifying the path of the home directory - * for the user specified in the usri1_name member. + * Pointer to a Unicode string specifying the path of the home directory + * for the user specified in the usri1_name member. */ - public WString usri1_home_dir; + public String usri1_home_dir; /** - * Pointer to a Unicode string that contains a comment to associate with + * Pointer to a Unicode string that contains a comment to associate with * the user account. */ - public WString usri1_comment; + public String usri1_comment; /** * Specifies a DWORD value that determines several features. */ public int usri1_flags; /** - * Pointer to a Unicode string specifying the path for the user's - * logon script file. + * Pointer to a Unicode string specifying the path for the user's + * logon script file. */ - public WString usri1_script_path; + public String usri1_script_path; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "usri1_name", "usri1_password", "usri1_password_age", "usri1_priv", "usri1_home_dir", "usri1_comment", "usri1_flags", "usri1_script_path" }); + public USER_INFO_1() { + super(W32APITypeMapper.UNICODE); + } + + public USER_INFO_1(Pointer memory) { + super(memory, Structure.ALIGN_DEFAULT, W32APITypeMapper.UNICODE); + read(); + } + + @Override + protected List getFieldOrder() { + return FIELDS; } } - + /** - * The USER_INFO_23 structure contains information about a user account, - * including the account name, the user's full name, a comment associated with the account, + * The USER_INFO_23 structure contains information about a user account, + * including the account name, the user's full name, a comment associated with the account, * and the user's security identifier (SID). * - * Note : - * The USER_INFO_23 structure supersedes the USER_INFO_20 structure. + * Note : + * The USER_INFO_23 structure supersedes the USER_INFO_20 structure. * It is recommended that applications use the USER_INFO_23 structure instead of the USER_INFO_20 structure. */ public static class USER_INFO_23 extends Structure { - public USER_INFO_23() { - super(); - } + public static final List FIELDS = createFieldsOrder( + "usri23_name", "usri23_full_name", "usri23_comment", "usri23_flags", "usri23_user_sid"); - public USER_INFO_23(Pointer memory) { - useMemory(memory); - read(); - } - - /** - * A pointer to a Unicode string that specifies the name of the user account. + /** + * A pointer to a Unicode string that specifies the name of the user account. * Calls to the NetUserSetInfo function ignore this member. */ - public WString usri23_name; - /** - * A pointer to a Unicode string that contains the full name of the user. + public String usri23_name; + /** + * A pointer to a Unicode string that contains the full name of the user. * This string can be a null string, or it can have any number of characters before the terminating null character. */ - public WString usri23_full_name; - /** - * A pointer to a Unicode string that contains a comment associated with the user account. + public String usri23_full_name; + /** + * A pointer to a Unicode string that contains a comment associated with the user account. * This string can be a null string, or it can have any number of characters before the terminating null character. */ - public WString usri23_comment; - /** - * This member can be one or more of the following values. - * Note that setting user account control flags may require certain privileges and control access rights. + public String usri23_comment; + /** + * This member can be one or more of the following values. + * Note that setting user account control flags may require certain privileges and control access rights. * For more information, see the Remarks section of the NetUserSetInfo function. - * Value Meaning + * Value Meaning * UF_SCRIPT The logon script executed. This value must be set. * UF_ACCOUNTDISABLE The user's account is disabled. * UF_HOMEDIR_REQUIRED The home directory is required. This value is ignored. @@ -209,9 +227,9 @@ * UF_TRUSTED_FOR_DELEGATION The account is enabled for delegation. This is a security-sensitive setting; accounts with this option enabled should be tightly controlled. This setting allows a service running under the account to assume a client's identity and authenticate as that user to other remote servers on the network. * UF_PASSWORD_EXPIRED The user's password has expired. Windows 2000: This value is not supported. * UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION The account is trusted to authenticate a user outside of the Kerberos security package and delegate that user through constrained delegation. This is a security-sensitive setting; accounts with this option enabled should be tightly controlled. This setting allows a service running under the account to assert a client's identity and authenticate as that user to specifically configured services on the network. Windows XP/2000: This value is not supported. - * + * * The following values describe the account type. Only one value can be set. You cannot change the account type using the NetUserSetInfo function. - * Value Meaning + * Value Meaning * UF_NORMAL_ACCOUNT This is a default account type that represents a typical user. * UF_TEMP_DUPLICATE_ACCOUNT This is an account for users whose primary account is in another domain. This account provides user access to this domain, but not to any domain that trusts this domain. The User Manager refers to this account type as a local user account. * UF_WORKSTATION_TRUST_ACCOUNT This is a computer account for a computer that is a member of this domain. @@ -219,117 +237,137 @@ * UF_INTERDOMAIN_TRUST_ACCOUNT This is a permit to trust account for a domain that trusts other domains. */ public int usri23_flags; - /** - * A pointer to a SID structure that contains the security identifier (SID) + /** + * A pointer to a SID structure that contains the security identifier (SID) * that uniquely identifies the user. The NetUserAdd and NetUserSetInfo functions ignore this member. */ public PSID.ByReference usri23_user_sid; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "usri23_name", "usri23_full_name", "usri23_comment", "usri23_flags", "usri23_user_sid" }); + + public USER_INFO_23() { + super(W32APITypeMapper.UNICODE); + } + + public USER_INFO_23(Pointer memory) { + super(memory, Structure.ALIGN_DEFAULT, W32APITypeMapper.UNICODE); + read(); + } + + @Override + protected List getFieldOrder() { + return FIELDS; } - } - + } + /** * The GROUP_USERS_INFO_0 structure contains global group member information. */ public static class GROUP_USERS_INFO_0 extends Structure { + public static final List FIELDS = createFieldsOrder("grui0_name"); + /** + * Pointer to a null-terminated Unicode character string that specifies a name. + */ + public String grui0_name; + public GROUP_USERS_INFO_0() { - super(); + super(W32APITypeMapper.UNICODE); } public GROUP_USERS_INFO_0(Pointer memory) { - super(memory); + super(memory, Structure.ALIGN_DEFAULT, W32APITypeMapper.UNICODE); read(); } - /** - * Pointer to a null-terminated Unicode character string that specifies a name. - */ - public WString grui0_name; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "grui0_name" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } - + /** * The LOCALGROUP_USERS_INFO_0 structure contains local group member information. */ public static class LOCALGROUP_USERS_INFO_0 extends Structure { + public static final List FIELDS = createFieldsOrder("lgrui0_name"); + /** + * Pointer to a Unicode string specifying the name of a local group to which the user belongs. + */ + public String lgrui0_name; + public LOCALGROUP_USERS_INFO_0() { - super(); + super(W32APITypeMapper.UNICODE); } public LOCALGROUP_USERS_INFO_0(Pointer memory) { - super(memory); + super(memory, Structure.ALIGN_DEFAULT, W32APITypeMapper.UNICODE); read(); } - /** - * Pointer to a Unicode string specifying the name of a local group to which the user belongs. - */ - public WString lgrui0_name; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "lgrui0_name" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } - + /** * The GROUP_INFO_0 structure contains the name of a global group in the security * database, which is the security accounts manager (SAM) database or, in the case * of domain controllers, the Active Directory. */ public static class GROUP_INFO_0 extends Structure { + public static final List FIELDS = createFieldsOrder("grpi0_name"); + + /** + * Pointer to a null-terminated Unicode character string that specifies + * the name of the global group. + */ + public String grpi0_name; + public GROUP_INFO_0() { - super(); + super(W32APITypeMapper.UNICODE); } public GROUP_INFO_0(Pointer memory) { - super(memory); + super(memory, Structure.ALIGN_DEFAULT, W32APITypeMapper.UNICODE); read(); } - /** - * Pointer to a null-terminated Unicode character string that specifies - * the name of the global group. - */ - public WString grpi0_name; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "grpi0_name" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } /** - * The GROUP_INFO_1 structure contains a global group name and a comment to + * The GROUP_INFO_1 structure contains a global group name and a comment to * associate with the group. */ - public static class GROUP_INFO_1 extends Structure { + public static class GROUP_INFO_1 extends Structure { + public static final List FIELDS = createFieldsOrder("grpi1_name", "grpi1_comment"); + + /** + * Pointer to a null-terminated Unicode character string that specifies + * the name of the global group. + */ + public String grpi1_name; + /** + * Pointer to a null-terminated Unicode character string that specifies + * a remark associated with the global group. This member can be a null + * string. The comment can contain MAXCOMMENTSZ characters. + */ + public String grpi1_comment; + public GROUP_INFO_1() { - super(); + super(W32APITypeMapper.UNICODE); } public GROUP_INFO_1(Pointer memory) { - super(memory); + super(memory, Structure.ALIGN_DEFAULT, W32APITypeMapper.UNICODE); read(); } - /** - * Pointer to a null-terminated Unicode character string that specifies - * the name of the global group. - */ - public WString grpi1_name; - /** - * Pointer to a null-terminated Unicode character string that specifies - * a remark associated with the global group. This member can be a null - * string. The comment can contain MAXCOMMENTSZ characters. - */ - public WString grpi1_comment; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "grpi1_name", "grpi1_comment" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } @@ -338,83 +376,91 @@ * name, identifier, and resource attributes. */ public static class GROUP_INFO_2 extends Structure { - public GROUP_INFO_2() { - super(); - } - - public GROUP_INFO_2(Pointer memory) { - super(memory); - read(); - } + public static final List FIELDS = createFieldsOrder( + "grpi2_name", "grpi2_comment", "grpi2_group_id", "grpi2_attributes"); /** - * Pointer to a null-terminated Unicode character string that + * Pointer to a null-terminated Unicode character string that * specifies the name of the global group. */ - public WString grpi2_name; + public String grpi2_name; /** - * Pointer to a null-terminated Unicode character string that contains a - * remark associated with the global group. This member can be a null string. - * The comment can contain MAXCOMMENTSZ characters. + * Pointer to a null-terminated Unicode character string that contains a + * remark associated with the global group. This member can be a null string. + * The comment can contain MAXCOMMENTSZ characters. */ - public WString grpi2_comment; + public String grpi2_comment; /** - * Specifies a DWORD value that contains the relative identifier (RID) of + * Specifies a DWORD value that contains the relative identifier (RID) of * the global group. */ public int grpi2_group_id; /** - * These attributes are hard-coded to SE_GROUP_MANDATORY, SE_GROUP_ENABLED, - * and SE_GROUP_ENABLED_BY_DEFAULT. + * These attributes are hard-coded to SE_GROUP_MANDATORY, SE_GROUP_ENABLED, + * and SE_GROUP_ENABLED_BY_DEFAULT. */ public int grpi2_attributes; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "grpi2_name", "grpi2_comment", "grpi2_group_id", "grpi2_attributes" }); + + public GROUP_INFO_2() { + super(W32APITypeMapper.UNICODE); + } + + public GROUP_INFO_2(Pointer memory) { + super(memory, Structure.ALIGN_DEFAULT, W32APITypeMapper.UNICODE); + read(); + } + + @Override + protected List getFieldOrder() { + return FIELDS; } } /** - * The GROUP_INFO_3 structure contains information about a global group, including + * The GROUP_INFO_3 structure contains information about a global group, including * name, security identifier (SID), and resource attributes. */ public static class GROUP_INFO_3 extends Structure { - public GROUP_INFO_3() { - super(); - } - - public GROUP_INFO_3(Pointer memory) { - super(memory); - read(); - } + public static final List FIELDS = createFieldsOrder( + "grpi3_name", "grpi3_comment", "grpi3_group_sid", "grpi3_attributes"); /** - * Pointer to a null-terminated Unicode character string that - * specifies the name of the global group. + * Pointer to a null-terminated Unicode character string that + * specifies the name of the global group. */ - public WString grpi3_name; + public String grpi3_name; /** - * Pointer to a null-terminated Unicode character string that - * contains a remark associated with the global group. This member can be - * a null string. The comment can contain MAXCOMMENTSZ characters. + * Pointer to a null-terminated Unicode character string that + * contains a remark associated with the global group. This member can be + * a null string. The comment can contain MAXCOMMENTSZ characters. */ - public WString grpi3_comment; + public String grpi3_comment; /** - * Pointer to a SID structure that contains the security identifier (SID) that + * Pointer to a SID structure that contains the security identifier (SID) that * uniquely identifies the global group. */ public PSID.ByReference grpi3_group_sid; /** - * These attributes are hard-coded to SE_GROUP_MANDATORY, SE_GROUP_ENABLED, and + * These attributes are hard-coded to SE_GROUP_MANDATORY, SE_GROUP_ENABLED, and * SE_GROUP_ENABLED_BY_DEFAULT. */ public int grpi3_attributes; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "grpi3_name", "grpi3_comment", "grpi3_group_sid", "grpi3_attributes" }); + + public GROUP_INFO_3() { + super(W32APITypeMapper.UNICODE); + } + + public GROUP_INFO_3(Pointer memory) { + super(memory, Structure.ALIGN_DEFAULT, W32APITypeMapper.UNICODE); + read(); + } + + @Override + protected List getFieldOrder() { + return FIELDS; } } - + // // Privilege levels (USER_INFO_X field usriX_priv (X = 0/1)). // @@ -422,5 +468,22 @@ int USER_PRIV_MASK = 3; int USER_PRIV_GUEST = 0; int USER_PRIV_USER = 1; - int USER_PRIV_ADMIN = 2; + int USER_PRIV_ADMIN = 2; + + // + // Bit values for the access permissions. ACCESS_ALL is a handy + // way to specify maximum permissions. These are used in + // acl_access field of access_list structures. + // + + int ACCESS_NONE = 0x00; + int ACCESS_READ = 0x01; + int ACCESS_WRITE = 0x02; + int ACCESS_CREATE = 0x04; + int ACCESS_EXEC = 0x08; + int ACCESS_DELETE = 0x10; + int ACCESS_ATRIB = 0x20; + int ACCESS_PERM = 0x40; + int ACCESS_ALL = ACCESS_READ | ACCESS_WRITE | ACCESS_CREATE | ACCESS_EXEC | ACCESS_DELETE | ACCESS_ATRIB | ACCESS_PERM; + int ACCESS_GROUP = 0x8000; } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/LMCons.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/LMCons.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/LMCons.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/LMCons.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,25 +1,34 @@ /* Copyright (c) 2010 Daniel Doubrovkine, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.win32.StdCallLibrary; - /** * Ported from LMCons.h. * @author dblock[at]dblock.org * Windows SDK 6.0A */ -public interface LMCons extends StdCallLibrary { +public interface LMCons { int NETBIOS_NAME_LEN = 16; // NetBIOS net name (bytes) /** diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/LMErr.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/LMErr.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/LMErr.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/LMErr.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,25 +1,34 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.win32.StdCallLibrary; - /** * Ported from LMErr.h. * @author dblock[at]dblock.org * Windows SDK 6.0A */ -public interface LMErr extends StdCallLibrary { +public interface LMErr { int NERR_Success = 0; int NERR_BASE = 2100; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/LMJoin.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/LMJoin.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/LMJoin.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/LMJoin.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,25 +1,34 @@ /* 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.win32.StdCallLibrary; - /** * Ported from LMJoin.h. * Windows SDK 6.0A. * @author dblock[at]dblock.org */ -public interface LMJoin extends StdCallLibrary { +public interface LMJoin { /** * Status of a workstation. diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/LMShare.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/LMShare.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/LMShare.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/LMShare.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,230 @@ +/* Copyright (c) 2015 Adam Marcionek, 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 java.util.List; + +import com.sun.jna.Pointer; +import com.sun.jna.Structure; +import com.sun.jna.win32.W32APITypeMapper; + +/** + * Ported from LMShare.h. + * Windows SDK 7.1 + * @author amarcionek[at]seven10storage.com + */ +public interface LMShare { + + // + // Share types (shi1_type and shi2_type fields). + // + + /** + * Disk Drive. + */ + int STYPE_DISKTREE = 0; + + /** + * Print Queue. + */ + int STYPE_PRINTQ = 1; + + /** + * Communication device. + */ + int STYPE_DEVICE = 2; + + /** + * Interprocess communication (IPC). + */ + int STYPE_IPC = 3; + + /** + * A temporary share. + */ + int STYPE_TEMPORARY = 0x40000000; + + /** + * Special share reserved for interprocess communication (IPC$) or remote administration of the server (ADMIN$). + * Can also refer to administrative shares such as C$, D$, E$, and so forth. For more information, see the network share functions. + */ + int STYPE_SPECIAL = 0x80000000; + + /** + * Contains information about the shared resource, including name of the resource, type and permissions, number of connections, and other pertinent information. + */ + public static class SHARE_INFO_2 extends Structure { + public static final List FIELDS = createFieldsOrder("shi2_netname", + "shi2_type", "shi2_remark", "shi2_permissions", "shi2_max_uses", "shi2_current_uses", + "shi2_path", "shi2_passwd"); + + /** + * Pointer to a Unicode string specifying the name of a shared resource. Calls to the NetShareSetInfo function ignore this member. + */ + public String shi2_netname; + + /** + * A combination of values that specify the type of share. Calls to the NetShareSetInfo function ignore this member. + * One of the following values may be specified. You can isolate these values by using the STYPE_MASK value. + * STYPE_DISKTREE, STYPE_PRINTQ, STYPE_DEVICE, STYPE_IPC, STYPE_TEMPORARY, STYPE_SPECIAL + */ + public int shi2_type; + + /** + * Pointer to a Unicode string specifying an optional comment about the shared resource. + */ + public String shi2_remark; + + /** + * Specifies a DWORD value that indicates the shared resource's permissions for servers running with share-level security. + * This member is ignored on a server running user-level security. This member can be any of the following values. + * Calls to the NetShareSetInfo function ignore this member. Note that Windows does not support share-level security. + * For more information about controlling access to securable objects, see Access Control, Privileges, and Securable Objects. + * NOTE: Bit masks are defined in LmAccess.Java + */ + public int shi2_permissions; + + /** + * Specifies a DWORD value that indicates the maximum number of concurrent connections that the shared resource can accommodate. + * The number of connections is unlimited if the value specified in this member is -1. + */ + public int shi2_max_uses; + + /** + * Specifies a DWORD value that indicates the number of current connections to the resource. Calls to the NetShareSetInfo function ignore this member. + */ + public int shi2_current_uses; + + /** + * Pointer to a Unicode string that contains the local path for the shared resource. For disks, this member is the path being shared. + * For print queues, this member is the name of the print queue being shared. Calls to the NetShareSetInfo function ignore this member. + */ + public String shi2_path; + + /** + * Pointer to a Unicode string that specifies the share's password (when the server is running with share-level security). If the server is + * running with user-level security, this member is ignored. Note that Windows does not support share-level security. + * This member can be no longer than SHPWLEN+1 bytes (including a terminating null character). Calls to the NetShareSetInfo function ignore this member. + */ + public String shi2_passwd; + + public SHARE_INFO_2() { + super(W32APITypeMapper.UNICODE); + } + + public SHARE_INFO_2(Pointer memory) { + super(memory, Structure.ALIGN_DEFAULT, W32APITypeMapper.UNICODE); + read(); + } + + @Override + protected List getFieldOrder() { + return FIELDS; + } + } + + /** + * Contains information about the shared resource, including name of the resource, type and permissions, number of connections, and other pertinent information. + */ + public static class SHARE_INFO_502 extends Structure { + public static final List FIELDS = createFieldsOrder("shi502_netname", + "shi502_type", "shi502_remark", "shi502_permissions", "shi502_max_uses", + "shi502_current_uses", "shi502_path", "shi502_passwd", "shi502_reserved", + "shi502_security_descriptor"); + + /** + * Pointer to a Unicode string specifying the name of a shared resource. Calls to the NetShareSetInfo function ignore this member. + */ + public String shi502_netname; + + /** + * A combination of values that specify the type of share. Calls to the NetShareSetInfo function ignore this member. + * One of the following values may be specified. You can isolate these values by using the STYPE_MASK value. + * STYPE_DISKTREE, STYPE_PRINTQ, STYPE_DEVICE, STYPE_IPC, STYPE_TEMPORARY, STYPE_SPECIAL + */ + public int shi502_type; + + /** + * Pointer to a Unicode string specifying an optional comment about the shared resource. + */ + public String shi502_remark; + + /** + * Specifies a DWORD value that indicates the shared resource's permissions for servers running with share-level security. + * This member is ignored on a server running user-level security. This member can be any of the following values. + * Calls to the NetShareSetInfo function ignore this member. Note that Windows does not support share-level security. + * For more information about controlling access to securable objects, see Access Control, Privileges, and Securable Objects. + * NOTE: Bit masks are defined in LmAccess.Java + */ + public int shi502_permissions; + + /** + * Specifies a DWORD value that indicates the maximum number of concurrent connections that the shared resource can accommodate. + * The number of connections is unlimited if the value specified in this member is -1. + */ + public int shi502_max_uses; + + /** + * Specifies a DWORD value that indicates the number of current connections to the resource. Calls to the NetShareSetInfo function ignore this member. + */ + public int shi502_current_uses; + + /** + * Pointer to a Unicode string that contains the local path for the shared resource. For disks, this member is the path being shared. + * For print queues, this member is the name of the print queue being shared. Calls to the NetShareSetInfo function ignore this member. + */ + public String shi502_path; + + /** + * Pointer to a Unicode string that specifies the share's password (when the server is running with share-level security). If the server is + * running with user-level security, this member is ignored. Note that Windows does not support share-level security. + * This member can be no longer than SHPWLEN+1 bytes (including a terminating null character). Calls to the NetShareSetInfo function ignore this member. + */ + public String shi502_passwd; + + /** + * Reserved; must be zero. Calls to the NetShareSetInfo function ignore this member. + */ + public int shi502_reserved; + + /** + * Specifies the SECURITY_DESCRIPTOR associated with this share. + */ + public Pointer shi502_security_descriptor; + + public SHARE_INFO_502() { + super(W32APITypeMapper.UNICODE); + } + + public SHARE_INFO_502(Pointer memory) { + super(memory, Structure.ALIGN_DEFAULT, W32APITypeMapper.UNICODE); + read(); + } + + @Override + protected List getFieldOrder() { + return FIELDS; + } + } +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/LowLevelMonitorConfigurationAPI.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/LowLevelMonitorConfigurationAPI.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/LowLevelMonitorConfigurationAPI.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/LowLevelMonitorConfigurationAPI.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,22 +1,29 @@ /* * Copyright 2014 Martin Steiger * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * 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 java.util.Arrays; import java.util.List; import com.sun.jna.Structure; @@ -33,8 +40,8 @@ /** * Contains information from a monitor's timing report. */ - class MC_TIMING_REPORT extends Structure - { + class MC_TIMING_REPORT extends Structure { + public static final List FIELDS = createFieldsOrder("dwHorizontalFrequencyInHZ", "dwVerticalFrequencyInHZ", "bTimingStatusByte"); /** * The monitor's horizontal synchronization frequency in Hz. */ @@ -46,15 +53,14 @@ public DWORD dwVerticalFrequencyInHZ; /** - * Timing status byte. For more information about this value, see the Display Data Channel Command + * Timing status byte. For more information about this value, see the Display Data Channel Command * Interface (DDC/CI) standard. */ public BYTE bTimingStatusByte; @Override - protected List getFieldOrder() - { - return Arrays.asList("dwHorizontalFrequencyInHZ", "dwVerticalFrequencyInHZ", "bTimingStatusByte"); + protected List getFieldOrder() { + return FIELDS; } } @@ -64,7 +70,7 @@ enum MC_VCP_CODE_TYPE { /** - * Momentary VCP code. Sending a command of this type causes the monitor to initiate a self-timed + * Momentary VCP code. Sending a command of this type causes the monitor to initiate a self-timed * operation and then revert to its original state. Examples include display tests and degaussing. */ MC_MOMENTARY, diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Mpr.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Mpr.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Mpr.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Mpr.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,429 @@ +/* Copyright (c) 2015 Adam Marcionek, 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.Native; +import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.WinDef.HWND; +import com.sun.jna.platform.win32.WinNT.HANDLE; +import com.sun.jna.platform.win32.WinNT.HANDLEByReference; +import com.sun.jna.platform.win32.Winnetwk.*; +import com.sun.jna.ptr.IntByReference; +import com.sun.jna.ptr.PointerByReference; +import com.sun.jna.win32.StdCallLibrary; +import com.sun.jna.win32.W32APIOptions; + +/** + * Ported from Winnetwk.h. Microsoft Windows SDK 8.1 + * + * @author amarcionek[at]gmail.com + */ + +public interface Mpr extends StdCallLibrary { + + Mpr INSTANCE = Native.loadLibrary("Mpr", Mpr.class, W32APIOptions.DEFAULT_OPTIONS); + + /** + * The WNetOpenEnum function starts an enumeration of network resources or + * existing connections. You can continue the enumeration by calling the + * WNetEnumResource function. + * + * @param dwScope + * Scope of the enumeration. This parameter can be one of the + * following values from NETRESOURCEScope: RESOURCE_CONNECTED, + * RESOURCE_CONTEXT, RESOURCE_GLOBALNET, RESOURCE_REMEMBERED + * @param dwType + * Resource types to be enumerated. This parameter can be a + * combination of the following values from NETRESOURCEType: + * RESOURCETYPE_ANY, RESOURCETYPE_DISK, RESOURCETYPE_PRINT + * @param dwUsage + * Resource usage type to be enumerated. This parameter can be a + * combination of the following values from NETRESOURCEUsage: 0, + * RESOURCEUSAGE_CONNECTABLE, RESOURCEUSAGE_CONTAINER, + * RESOURCEUSAGE_ATTACHED, RESOURCEUSAGE_ALL + * @param lpNETRESOURCE + * Pointer to a NETRESOURCE structure that specifies the + * container to enumerate. If the dwScope parameter is not + * RESOURCE_GLOBALNET, this parameter must be NULL. If this + * parameter is NULL, the root of the network is assumed. (The + * system organizes a network as a hierarchy; the root is the + * topmost container in the network.) If this parameter is not + * NULL, it must point to a NETRESOURCE structure. This structure + * can be filled in by the application or it can be returned by a + * call to the WNetEnumResource function. The NETRESOURCE + * structure must specify a container resource; that is, the + * RESOURCEUSAGE_CONTAINER value must be specified in the dwUsage + * parameter. To enumerate all network resources, an application + * can begin the enumeration by calling WNetOpenEnum with the + * lpNETRESOURCE parameter set to NULL, and then use the returned + * handle to call WNetEnumResource to enumerate resources. If one + * of the resources in the NETRESOURCE array returned by the + * WNetEnumResource function is a container resource, you can + * call WNetOpenEnum to open the resource for further + * enumeration. + * @param lphEnum + * Pointer to an enumeration handle that can be used in a + * subsequent call to WNetEnumResource. + * @return NO_ERROR if the function succeeds, otherwise a + * system error code. See MSDN documentation for common error + * values: + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385478 + * (v=vs.85).aspx + */ + public int WNetOpenEnum(int dwScope, int dwType, int dwUsage, NETRESOURCE.ByReference lpNETRESOURCE, HANDLEByReference lphEnum); + + /** + * The WNetEnumResource function continues an enumeration of network + * resources that was started by a call to the WNetOpenEnum function. + * + * @param hEnum + * [in] Handle that identifies an enumeration instance. This + * handle must be returned by the WNetOpenEnum function. + * @param lpcCount + * [in, out] Pointer to a variable specifying the number of + * entries requested. If the number requested is -1, the function + * returns as many entries as possible. If the function succeeds, + * on return the variable pointed to by this parameter contains + * the number of entries actually read. + * @param lpBuffer + * [out] Pointer to the buffer that receives the enumeration + * results. The results are returned as an array of NETRESOURCE + * structures. Note that the buffer you allocate must be large + * enough to hold the structures, plus the strings to which their + * members point. For more information, see the Remarks section + * on MSDN: + * https://msdn.microsoft.com/en-us/library/windows/desktop/ + * aa385449(v=vs.85).aspx The buffer is valid until the next call + * using the handle specified by the hEnum parameter. The order + * of NETRESOURCE structures in the array is not predictable. + * @param lpBufferSize + * [in, out] Pointer to a variable that specifies the size of the + * lpBuffer parameter, in bytes. If the buffer is too small to + * receive even one entry, this parameter receives the required + * size of the buffer. + * @return If the function succeeds, the return value is one of the + * following values: NO_ERROR - The enumeration succeeded, and the + * buffer contains the requested data. The calling application can + * continue to call WNetEnumResource to complete the enumeration. + * ERROR_NO_MORE_ITEMS - There are no more entries. The buffer + * contents are undefined. If the function fails, see MSDN + * documentation for common error values: + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385478 + * (v=vs.85).aspx + */ + public int WNetEnumResource(HANDLE hEnum, IntByReference lpcCount, Pointer lpBuffer, IntByReference lpBufferSize); + + /** + * The WNetCloseEnum function ends a network resource enumeration started by + * a call to the WNetOpenEnum function. + * + * @param hEnum + * [in] Handle that identifies an enumeration instance. This + * handle must be returned by the WNetOpenEnum function. + * @return NO_ERROR if the function succeeds, otherwise a + * system error code. See MSDN documentation for common error + * values: + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385431 + * (v=vs.85).aspx + */ + int WNetCloseEnum(HANDLE hEnum); + + /** + * The WNetGetUniversalName function takes a drive-based path for a network + * resource and returns an information structure that contains a more + * universal form of the name. + * + * @param lpLocalPath + * [in] A pointer to a constant null-terminated string that is a + * drive-based path for a network resource. For example, if drive + * H has been mapped to a network drive share, and the network + * resource of interest is a file named Sample.doc in the + * directory \Win32\Examples on that share, the drive-based path + * is H:\Win32\Examples\Sample.doc. + * @param dwInfoLevel + * [in] The type of structure that the function stores in the + * buffer pointed to by the lpBuffer parameter. This parameter + * can be one of the following values defined in the + * Winnetwk.java. UNIVERSAL_NAME_INFO_LEVEL - The function stores + * a UNIVERSAL_NAME_INFO structure in the buffer. + * REMOTE_NAME_INFO_LEVEL - The function stores a + * REMOTE_NAME_INFO structure in the buffer. The + * UNIVERSAL_NAME_INFO structure points to a Universal Naming + * Convention (UNC) name string. The REMOTE_NAME_INFO structure + * points to a UNC name string and two additional connection + * information strings. For more information, see the following + * Remarks section. + * @param lpBuffer + * [out] A pointer to a buffer that receives the structure + * specified by the dwInfoLevel parameter. + * @param lpBufferSize + * [in,out] A pointer to a variable that specifies the size, in + * bytes, of the buffer pointed to by the lpBuffer parameter. If + * the function succeeds, it sets the variable pointed to by + * lpBufferSize to the number of bytes stored in the buffer. If + * the function fails because the buffer is too small, this + * location receives the required buffer size, and the function + * returns ERROR_MORE_DATA. + * @return If the function succeeds, the return value is NO_ERROR, otherwise + * see MSDN for common error codes: + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385474 + * (v=vs.85).aspx + */ + int WNetGetUniversalName(String lpLocalPath, int dwInfoLevel, Pointer lpBuffer, IntByReference lpBufferSize); + + /** + * The WNetUseConnection function makes a connection to a network resource. + * The function can redirect a local device to a network resource. + * + * The WNetUseConnection function is similar to the WNetAddConnection3 + * function. The main difference is that WNetUseConnection can automatically + * select an unused local device to redirect to the network resource. + * + * @param hwndOwner + * [in] Handle to a window that the provider of network resources + * can use as an owner window for dialog boxes. Use this + * parameter if you set the CONNECT_INTERACTIVE value in the + * dwFlags parameter. + * @param lpNETRESOURCE + * [in] Pointer to a NETRESOURCE structure that specifies details + * of the proposed connection. The structure contains information + * about the network resource, the local device, and the network + * resource provider. + * + * You must specify the following members of the NETRESOURCE + * structure. The WNetUseConnection function ignores the other + * members of the NETRESOURCE structure. For more information, + * see the descriptions following for the dwFlags parameter. + * + * dwType Specifies the type of resource to connect to. It is + * most efficient to specify a resource type in this member, such + * as RESOURCETYPE_DISK or RESOURCETYPE_PRINT. However, if the + * lpLocalName member is NULL, or if it points to an empty string + * and CONNECT_REDIRECT is not set, dwType can be + * RESOURCETYPE_ANY. + * + * This method works only if the function does not automatically + * choose a device to redirect to the network resource. Although + * this member is required, its information may be ignored by the + * network service provider lpLocalName Pointer to a + * null-terminated string that specifies the name of a local + * device to be redirected, such as "F:" or "LPT1". The string is + * treated in a case-insensitive manner. If the string is empty, + * or if lpLocalName is NULL, a connection to the network occurs + * without redirection. If the CONNECT_REDIRECT value is set in + * the dwFlags parameter, or if the network requires a redirected + * local device, the function chooses a local device to redirect + * and returns the name of the device in the lpAccessName + * parameter. lpRemoveName Pointer to a null-terminated string + * that specifies the network resource to connect to. The string + * can be up to MAX_PATH characters in length, and it must follow + * the network provider's naming conventions. lpProvider Pointer + * to a null-terminated string that specifies the network + * provider to connect to. If lpProvider is NULL, or if it points + * to an empty string, the operating system attempts to determine + * the correct provider by parsing the string pointed to by the + * lpRemoteName member. If this member is not NULL, the operating + * system attempts to make a connection only to the named network + * provider. You should set this member only if you know the + * network provider you want to use. Otherwise, let the operating + * system determine which provider the network name maps to. + * @param lpPassword + * [in] Pointer to a constant null-terminated string that + * specifies a password to be used in making the network + * connection. If lpPassword is NULL, the function uses the + * current default password associated with the user specified by + * lpUserID. If lpPassword points to an empty string, the + * function does not use a password. If the connection fails + * because of an invalid password and the CONNECT_INTERACTIVE + * value is set in the dwFlags parameter, the function displays a + * dialog box asking the user to type the password. + * @param lpUserID + * [in] Pointer to a constant null-terminated string that + * specifies a user name for making the connection. If lpUserID + * is NULL, the function uses the default user name. (The user + * context for the process provides the default user name.) The + * lpUserID parameter is specified when users want to connect to + * a network resource for which they have been assigned a user + * name or account other than the default user name or account. + * The user-name string represents a security context. It may be + * specific to a network provider. For security context, see + * https://msdn.microsoft.com/en-us/library/windows/desktop/ + * ms721625(v=vs.85).aspx + * @param dwFlags + * [in] Set of bit flags describing the connection. This + * parameter can be any combination of the values in ConnectFlag. + * @param lpAccessName + * [out] Pointer to a buffer that receives system requests on the + * connection. This parameter can be NULL. If this parameter is + * specified, and the lpLocalName member of the NETRESOURCE + * structure specifies a local device, this buffer receives the + * local device name. If lpLocalName does not specify a device + * and the network requires a local device redirection, or if the + * CONNECT_REDIRECT value is set, this buffer receives the name + * of the redirected local device. Otherwise, the name copied + * into the buffer is that of a remote resource. If specified, + * this buffer must be at least as large as the string pointed to + * by the lpRemoteName member. + * @param lpBufferSize + * [in, out] Pointer to a variable that specifies the size of the + * lpAccessName buffer, in characters. If the call fails because + * the buffer is not large enough, the function returns the + * required buffer size in this location. For more information, + * see the descriptions of the lpAccessName parameter and the + * ERROR_MORE_DATA error code in the Return Values section. + * @param lpResult + * [out] Pointer to a variable that receives additional + * information about the connection. This parameter can be the + * following value: + * + * ConnectFlag.CONNECT_LOCALDRIVE - If this flag is set, the + * connection was made using a local device redirection. If the + * lpAccessName parameter points to a buffer, the local device + * name is copied to the buffer. + * @return NO_ERROR if the function succeeds, otherwise a + * system error code. See MSDN documentation for common error + * values: + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385482 + * (v=vs.85).aspx + */ + public int WNetUseConnection(HWND hwndOwner, NETRESOURCE lpNETRESOURCE, String lpPassword, String lpUserID, int dwFlags, + PointerByReference lpAccessName, IntByReference lpBufferSize, IntByReference lpResult); + + /** + * The WNetAddConnection3 function makes a connection to a network resource. + * The function can redirect a local device to the network resource. + * + * @param hwndOwner + * [in] Handle to a window that the provider of network resources + * can use as an owner window for dialog boxes. Use this + * parameter if you set the CONNECT_INTERACTIVE value in the + * dwFlags parameter. + * @param lpNETRESOURCE + * [in] Pointer to a NETRESOURCE structure that specifies details + * of the proposed connection. The structure contains information + * about the network resource, the local device, and the network + * resource provider. + * + * You must specify the following members of the NETRESOURCE + * structure. The WNetUseConnection function ignores the other + * members of the NETRESOURCE structure. For more information, + * see the descriptions following for the dwFlags parameter. + * + * dwType Specifies the type of resource to connect to. It is + * most efficient to specify a resource type in this member, such + * as RESOURCETYPE_DISK or RESOURCETYPE_PRINT. However, if the + * lpLocalName member is NULL, or if it points to an empty string + * and CONNECT_REDIRECT is not set, dwType can be + * RESOURCETYPE_ANY. + * + * This method works only if the function does not automatically + * choose a device to redirect to the network resource. Although + * this member is required, its information may be ignored by the + * network service provider lpLocalName Pointer to a + * null-terminated string that specifies the name of a local + * device to be redirected, such as "F:" or "LPT1". The string is + * treated in a case-insensitive manner. If the string is empty, + * or if lpLocalName is NULL, a connection to the network occurs + * without redirection. If the CONNECT_REDIRECT value is set in + * the dwFlags parameter, or if the network requires a redirected + * local device, the function chooses a local device to redirect + * and returns the name of the device in the lpAccessName + * parameter. lpRemoveName Pointer to a null-terminated string + * that specifies the network resource to connect to. The string + * can be up to MAX_PATH characters in length, and it must follow + * the network provider's naming conventions. lpProvider Pointer + * to a null-terminated string that specifies the network + * provider to connect to. If lpProvider is NULL, or if it points + * to an empty string, the operating system attempts to determine + * the correct provider by parsing the string pointed to by the + * lpRemoteName member. If this member is not NULL, the operating + * system attempts to make a connection only to the named network + * provider. You should set this member only if you know the + * network provider you want to use. Otherwise, let the operating + * system determine which provider the network name maps to. + * @param lpPassword + * [in] Pointer to a constant null-terminated string that + * specifies a password to be used in making the network + * connection. If lpPassword is NULL, the function uses the + * current default password associated with the user specified by + * lpUserID. If lpPassword points to an empty string, the + * function does not use a password. If the connection fails + * because of an invalid password and the CONNECT_INTERACTIVE + * value is set in the dwFlags parameter, the function displays a + * dialog box asking the user to type the password. + * @param lpUserID + * [in] Pointer to a constant null-terminated string that + * specifies a user name for making the connection. If lpUserID + * is NULL, the function uses the default user name. (The user + * context for the process provides the default user name.) The + * lpUserID parameter is specified when users want to connect to + * a network resource for which they have been assigned a user + * name or account other than the default user name or account. + * The user-name string represents a security context. It may be + * specific to a network provider. For security context, see + * https://msdn.microsoft.com/en-us/library/windows/desktop/ + * ms721625(v=vs.85).aspx + * @param dwFlags + * [in] Set of bit flags describing the connection. This + * parameter can be any combination of the values in ConnectFlag. + */ + public int WNetAddConnection3(HWND hwndOwner, NETRESOURCE lpNETRESOURCE, String lpPassword, String lpUserID, int dwFlags); + + /** + * The WNetCancelConnection2 function cancels an existing network + * connection. You can also call the function to remove remembered network + * connections that are not currently connected. + * + * @param lpName + * [in] Pointer to a constant null-terminated string that + * specifies the name of either the redirected local device or + * the remote network resource to disconnect from. If this + * parameter specifies a redirected local device, the function + * cancels only the specified device redirection. If the + * parameter specifies a remote network resource, all connections + * without devices are canceled. + * @param dwFlags + * [in] Connection type. The following values are defined. 0 - + * The system does not update information about the connection. + * If the connection was marked as persistent in the registry, + * the system continues to restore the connection at the next + * logon. If the connection was not marked as persistent, the + * function ignores the setting of the CONNECT_UPDATE_PROFILE + * flag. CONNECT_UPDATE_PROFILE - The system updates the user + * profile with the information that the connection is no longer + * a persistent one. The system will not restore this connection + * during subsequent logon operations. (Disconnecting resources + * using remote names has no effect on persistent connections.) + * @param fForce + * [in] Specifies whether the disconnection should occur if there + * are open files or jobs on the connection. If this parameter is + * FALSE, the function fails if there are open files or jobs. + * @return NO_ERROR if the function succeeds, otherwise a + * system error code. See MSDN documentation for common error + * values: + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385482 + * (v=vs.85).aspx + */ + public int WNetCancelConnection2(String lpName, int dwFlags, boolean fForce); +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Msi.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Msi.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Msi.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Msi.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,12 +1,24 @@ -/* This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. +/* + * 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; @@ -20,78 +32,77 @@ */ public interface Msi extends StdCallLibrary { - Msi INSTANCE = (Msi) - Native.loadLibrary("msi", Msi.class, W32APIOptions.UNICODE_OPTIONS); + Msi INSTANCE = Native.loadLibrary("msi", Msi.class, W32APIOptions.DEFAULT_OPTIONS); /** * The component being requested is disabled on the computer. */ - static int INSTALLSTATE_NOTUSED = -7; + int INSTALLSTATE_NOTUSED = -7; /** * The configuration data is corrupt. */ - static int INSTALLSTATE_BADCONFIG = -6; + int INSTALLSTATE_BADCONFIG = -6; /** * The installation is suspended or in progress. */ - static int INSTALLSTATE_INCOMPLETE = -5; + int INSTALLSTATE_INCOMPLETE = -5; /** * The feature must run from the source, and the source is unavailable. */ - static int INSTALLSTATE_SOURCEABSENT = -4; + int INSTALLSTATE_SOURCEABSENT = -4; /** * The return buffer is full. */ - static int INSTALLSTATE_MOREDATA = -3; + int INSTALLSTATE_MOREDATA = -3; /** * An invalid parameter was passed to the function. */ - static int INSTALLSTATE_INVALIDARG = -2; + int INSTALLSTATE_INVALIDARG = -2; /** * An unrecognized product or feature was specified. */ - static int INSTALLSTATE_UNKNOWN = -1; + int INSTALLSTATE_UNKNOWN = -1; /** * The feature is broken. */ - static int INSTALLSTATE_BROKEN = 0; + int INSTALLSTATE_BROKEN = 0; /** * The advertised feature. */ - static int INSTALLSTATE_ADVERTISED = 1; + int INSTALLSTATE_ADVERTISED = 1; /** * The component is being removed. */ - static int INSTALLSTATE_REMOVED = 1; + int INSTALLSTATE_REMOVED = 1; /** * The feature was uninstalled. */ - static int INSTALLSTATE_ABSENT = 2; + int INSTALLSTATE_ABSENT = 2; /** * The feature was installed on the local drive. */ - static int INSTALLSTATE_LOCAL = 3; + int INSTALLSTATE_LOCAL = 3; /** * The feature must run from the source, CD-ROM, or network. */ - static int INSTALLSTATE_SOURCE = 4; + int INSTALLSTATE_SOURCE = 4; /** * The feature is installed in the default location: local or source. */ - static int INSTALLSTATE_DEFAULT = 5; + int INSTALLSTATE_DEFAULT = 5; /** * The MsiGetComponentPath function returns the full path to an installed component. If the key path for the diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Netapi32.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Netapi32.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Netapi32.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Netapi32.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2010 Daniel Doubrovkine, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * 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). * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; @@ -29,8 +40,7 @@ */ public interface Netapi32 extends StdCallLibrary { - Netapi32 INSTANCE = (Netapi32) Native.loadLibrary("Netapi32", - Netapi32.class, W32APIOptions.UNICODE_OPTIONS); + Netapi32 INSTANCE = Native.loadLibrary("Netapi32", Netapi32.class, W32APIOptions.DEFAULT_OPTIONS); /** * Retrieves join status information for the specified computer. @@ -426,6 +436,44 @@ * @return * If the function succeeds, the return value is NERR_Success. */ - public int NetUserGetInfo( String servername, String username, int level, PointerByReference bufptr ); - + public int NetUserGetInfo(String servername, String username, int level, PointerByReference bufptr); + + /** + * Shares a server resource. + * + * @param servername [in] + * Pointer to a string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. + * If this parameter is NULL, the local computer is used. + * @param level [in] + * Specifies the information level of the data. This parameter can be one of the following values: + * 2 - Specifies information about the shared resource, including the name of the resource, type and permissions, and number of connections. + * The buf parameter points to a SHARE_INFO_2 structure. + * 502 - Specifies information about the shared resource, including the name of the resource, type and permissions, number of connections, and other pertinent information. + * The buf parameter points to a SHARE_INFO_502 structure. + * 503 - Specifies information about the shared resource, including the name of the resource, type and permissions, number of connections, and other pertinent information. + * The buf parameter points to a SHARE_INFO_503 structure. + * @param buf [in] + * Pointer to the buffer that specifies the data. The format of this data depends on the value of the level parameter. + * For more information, see Network Management Function Buffers (https://msdn.microsoft.com/en-us/library/windows/desktop/aa370676(v=vs.85).aspx) + * @param parm_err [out] + * Pointer to a value that receives the index of the first member of the share information structure that causes the ERROR_INVALID_PARAMETER error. If this parameter is NULL, the + * index is not returned on error. For more information, see the NetShareSetInfo function. + * @return If the function succeeds, the return value is NERR_Success. If the function fails, the return value can be an error code as seen on MSDN. + */ + public int NetShareAdd(String servername, int level, Pointer buf, IntByReference parm_err); + + /** + * Deletes a share name from a server's list of shared resources, disconnecting all connections to the shared resource. + * + * @param servername [in] + * Pointer to a string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. + * If this parameter is NULL, the local computer is used. + * @param netname [in] + * Pointer to a string that specifies the name of the share to delete. + * @param reserved + * Reserved, must be zero. + * @return If the function succeeds, the return value is LMErr.NERR_Success. + * If the function fails, the return value can be an error code as seen on MSDN. + */ + public int NetShareDel(String servername, String netname, int reserved); } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Netapi32Util.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Netapi32Util.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Netapi32Util.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Netapi32Util.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2010 Daniel Doubrovkine, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/NtDll.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/NtDll.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/NtDll.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/NtDll.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,18 +1,30 @@ /* Copyright (c) 2010 Daniel Doubrovkine, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.Native; +import com.sun.jna.Pointer; import com.sun.jna.Structure; import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.ptr.IntByReference; @@ -25,8 +37,7 @@ */ public interface NtDll extends StdCallLibrary { - NtDll INSTANCE = (NtDll) Native.loadLibrary("NtDll", - NtDll.class, W32APIOptions.UNICODE_OPTIONS); + NtDll INSTANCE = Native.loadLibrary("NtDll", NtDll.class, W32APIOptions.DEFAULT_OPTIONS); /** * The ZwQueryKey routine provides information about the class of a registry key, @@ -52,4 +63,65 @@ */ public int ZwQueryKey(HANDLE KeyHandle, int KeyInformationClass, Structure KeyInformation, int Length, IntByReference ResultLength); -} \ No newline at end of file + + /** + * The NtSetSecurityObject routine sets an object's security state. + * @param handle [in] + * Handle for the object whose security state is to be set. This handle must have the access + * specified in the Meaning column of the table shown in the description of the + * SecurityInformation parameter. + * @param SecurityInformation [in] + * SECURITY_INFORMATION value specifying the information to be set. Can be a combination of + * one or more of the following: + * DACL_SECURITY_INFORMATION + * Indicates the discretionary access control list (DACL) of the object is to be set. Requires WRITE_DAC access. + * GROUP_SECURITY_INFORMATION + * Indicates the primary group identifier of the object is to be set. Requires WRITE_OWNER access. + * OWNER_SECURITY_INFORMATION + * Indicates the owner identifier of the object is to be set. Requires WRITE_OWNER access. + * SACL_SECURITY_INFORMATION + * Indicates the system ACL (SACL) of the object is to be set. Requires ACCESS_SYSTEM_SECURITY access. + * @param pSecurityDescriptor [in] + * Pointer to the security descriptor to be set for the object. + * @return + * NtSetSecurityObject returns STATUS_SUCCESS or an appropriate error status. + */ + public int NtSetSecurityObject(HANDLE handle, int SecurityInformation, Pointer pSecurityDescriptor); + + /** + * The NtQuerySecurityObject routine retrieves a copy of an object's security descriptor. + * + * @param handle [in] + * Handle for the object whose security descriptor is to be queried. This handle must have the access specified + * in the Meaning column of the table shown in the description of the SecurityInformation parameter. + * @param SecurityInformation [in] + * Pointer to a SECURITY_INFORMATION value specifying the information to be queried. Can be a combination of + * one or more of the following: + * DACL_SECURITY_INFORMATION + * Indicates the discretionary access control list (DACL) of the object is to be set. Requires WRITE_DAC access. + * GROUP_SECURITY_INFORMATION + * Indicates the primary group identifier of the object is to be set. Requires WRITE_OWNER access. + * OWNER_SECURITY_INFORMATION + * Indicates the owner identifier of the object is to be set. Requires WRITE_OWNER access. + * SACL_SECURITY_INFORMATION + * Indicates the system ACL (SACL) of the object is to be set. Requires ACCESS_SYSTEM_SECURITY access. + * @param SecurityDescriptor [out] + * Pointer to the security descriptor to be set for the object. + * @param Length [in] + * Size, in bytes, of the buffer pointed to by SecurityDescriptor. + * @param LengthNeeded [in] + * Pointer to a caller-allocated variable that receives the number of bytes required to store the copied security descriptor. + * @return + * NtQuerySecurityObject returns STATUS_SUCCESS or an appropriate error status. + */ + public int NtQuerySecurityObject(HANDLE handle, int SecurityInformation, Pointer SecurityDescriptor, int Length, IntByReference LengthNeeded); + + /** + * Converts the specified NTSTATUS code to its equivalent system error code. + * @param Status [in] + * The NTSTATUS code to be converted. + * @return The function returns the corresponding system error code. ERROR_MR_MID_NOT_FOUND is returned when the specified NTSTATUS code + * does not have a corresponding system error code. + */ + public int RtlNtStatusToDosError(int Status); +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/NtDllUtil.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/NtDllUtil.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/NtDllUtil.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/NtDllUtil.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2010 Daniel Doubrovkine, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Ntifs.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Ntifs.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Ntifs.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Ntifs.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,402 @@ +/* Copyright (c) 2016 Adam Marcionek, 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 java.util.Arrays; +import java.util.List; + +import com.sun.jna.Native; +import com.sun.jna.Pointer; +import com.sun.jna.Structure; +import com.sun.jna.Union; +import com.sun.jna.win32.W32APITypeMapper; + +/** + * Ported from Ntifs.h + * Microsoft Windows WDK 10 + * @author amarcionek[at]gmail.com + */ +public interface Ntifs extends WinDef, BaseTSD { + + // Defined in winnt.h + public int MAXIMUM_REPARSE_DATA_BUFFER_SIZE = 16 * 1024; + + // 1 long and 2 shorts aligned on longlong + public int REPARSE_BUFFER_HEADER_SIZE = 8; + + public int SYMLINK_FLAG_RELATIVE = 1; + + public static class SymbolicLinkReparseBuffer extends Structure { + + public static class ByReference extends SymbolicLinkReparseBuffer implements Structure.ByReference { + public ByReference() { + } + + public ByReference(Pointer memory) { + super(memory); + } + } + + /** + * Offset, in bytes, of the substitute name string in the PathBuffer array. + * Note that this offset must be divided by sizeof(WCHAR) to get the array index. + */ + public short SubstituteNameOffset = 0; + + /** + * Length, in bytes, of the substitute name string. If this string is NULL-terminated, + * SubstituteNameLength does not include space for the UNICODE_NULL character. + */ + public short SubstituteNameLength = 0; + + /** + * Offset, in bytes, of the print name string in the PathBuffer array. + * Note that this offset must be divided by sizeof(WCHAR) to get the array index. + */ + public short PrintNameOffset = 0; + + /** + * Length, in bytes, of the print name string. If this string is NULL-terminated, + * PrintNameLength does not include space for the UNICODE_NULL character. + */ + public short PrintNameLength = 0; + + /** + * Used to indicate if the given symbolic link is an absolute or relative symbolic link. + * If Flags contains SYMLINK_FLAG_RELATIVE, the symbolic link contained in the PathBuffer + * array (at offset SubstitueNameOffset) is processed as a relative symbolic link; otherwise, + * it is processed as an absolute symbolic link. + */ + public int Flags = 0; + + /** + * First character of the path string. This is followed in memory by the remainder of the string. + * The path string contains the substitute name string and print name string. The substitute name + * and print name strings can appear in any order in the PathBuffer. (To locate the substitute + * name and print name strings in the PathBuffer, use the SubstituteNameOffset, SubstituteNameLength, + * PrintNameOffset, and PrintNameLength members.) + * NOTE: MAXIMUM_REPARSE_DATA_BUFFER_SIZE is chosen here based on documentation. Because chars are two + * bytes, the actual array size needs to be divided by 2 + */ + public char[] PathBuffer = new char[MAXIMUM_REPARSE_DATA_BUFFER_SIZE / 2]; + + public static int sizeOf() { + return Native.getNativeSize(MountPointReparseBuffer.class, null); + } + + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "SubstituteNameOffset", "SubstituteNameLength", "PrintNameOffset", "PrintNameLength", "Flags", "PathBuffer" }); + } + + public SymbolicLinkReparseBuffer() { + super(W32APITypeMapper.UNICODE); + } + + public SymbolicLinkReparseBuffer(Pointer memory) { + super(memory, Structure.ALIGN_DEFAULT, W32APITypeMapper.UNICODE); + read(); + } + + public SymbolicLinkReparseBuffer(String substituteName, String printName, int Flags) { + super(); + String bothNames = substituteName + printName; + PathBuffer = bothNames.toCharArray(); + this.SubstituteNameOffset = 0; + this.SubstituteNameLength = (short) (substituteName.length() * 2); + this.PrintNameOffset = (short) (substituteName.length() * 2); + this.PrintNameLength = (short) (printName.length() * 2); + this.Flags = Flags; + write(); + } + + public SymbolicLinkReparseBuffer(short SubstituteNameOffset, short SubstituteNameLength, short PrintNameOffset, short PrintNameLength, int Flags, String PathBuffer) { + super(); + this.SubstituteNameOffset = SubstituteNameOffset; + this.SubstituteNameLength = SubstituteNameLength; + this.PrintNameOffset = PrintNameOffset; + this.PrintNameLength = PrintNameLength; + this.Flags = Flags; + this.PathBuffer = PathBuffer.toCharArray(); + write(); + } + + /** + * @return the print name in a String + */ + public String getPrintName() { + return String.copyValueOf(PathBuffer, PrintNameOffset / 2, PrintNameLength / 2); + } + + /** + * @return the substitute name in a String + */ + public String getSubstituteName() { + return String.copyValueOf(PathBuffer, SubstituteNameOffset / 2, SubstituteNameLength / 2); + } + } + + public static class MountPointReparseBuffer extends Structure { + + public static class ByReference extends MountPointReparseBuffer implements Structure.ByReference { + public ByReference() { + } + + public ByReference(Pointer memory) { + super(memory); + } + } + + /** + * Offset, in bytes, of the substitute name string in the PathBuffer array. + * Note that this offset must be divided by sizeof(WCHAR) to get the array index. + */ + public short SubstituteNameOffset = 0; + + /** + * Length, in bytes, of the substitute name string. If this string is NULL-terminated, + * SubstituteNameLength does not include space for the UNICODE_NULL character. + */ + public short SubstituteNameLength = 0; + + /** + * Offset, in bytes, of the print name string in the PathBuffer array. + * Note that this offset must be divided by sizeof(WCHAR) to get the array index. + */ + public short PrintNameOffset = 0; + + /** + * Length, in bytes, of the print name string. If this string is NULL-terminated, + * PrintNameLength does not include space for the UNICODE_NULL character. + */ + public short PrintNameLength = 0; + + /** + * First character of the path string. This is followed in memory by the remainder of the string. + * The path string contains the substitute name string and print name string. The substitute name + * and print name strings can appear in any order in the PathBuffer. (To locate the substitute + * name and print name strings in the PathBuffer, use the SubstituteNameOffset, SubstituteNameLength, + * PrintNameOffset, and PrintNameLength members.) + * NOTE: MAXIMUM_REPARSE_DATA_BUFFER_SIZE is chosen here based on documentation. Because chars are two + * bytes, the actual array size needs to be divided by 2 + */ + public char[] PathBuffer = new char[MAXIMUM_REPARSE_DATA_BUFFER_SIZE / 2]; + + public static int sizeOf() { + return Native.getNativeSize(MountPointReparseBuffer.class, null); + } + + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "SubstituteNameOffset", "SubstituteNameLength", "PrintNameOffset", "PrintNameLength", "PathBuffer" }); + } + + public MountPointReparseBuffer() { + super(W32APITypeMapper.UNICODE); + } + + public MountPointReparseBuffer(Pointer memory) { + super(memory, Structure.ALIGN_DEFAULT, W32APITypeMapper.UNICODE); + read(); + } + + public MountPointReparseBuffer(String substituteName, String printName) { + super(); + String bothNames = substituteName + printName; + PathBuffer = bothNames.toCharArray(); + this.SubstituteNameOffset = 0; + this.SubstituteNameLength = (short) substituteName.length(); + this.PrintNameOffset = (short) (substituteName.length() * 2); + this.PrintNameLength = (short) (printName.length() * 2); + write(); + } + + public MountPointReparseBuffer(short SubstituteNameOffset, short SubstituteNameLength, short PrintNameOffset, short PrintNameLength, String PathBuffer) { + super(); + this.SubstituteNameOffset = SubstituteNameOffset; + this.SubstituteNameLength = SubstituteNameLength; + this.PrintNameOffset = PrintNameOffset; + this.PrintNameLength = PrintNameLength; + this.PathBuffer = PathBuffer.toCharArray(); + write(); + } + } + + public static class GenericReparseBuffer extends Structure { + + public static class ByReference extends GenericReparseBuffer implements Structure.ByReference { + public ByReference() { + } + + public ByReference(Pointer memory) { + super(memory); + } + } + + /** + * Microsoft-defined data for the reparse point. + * NOTE: MAXIMUM_REPARSE_DATA_BUFFER_SIZE is chosen based on documentation + */ + public byte[] DataBuffer = new byte[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; + + public static int sizeOf() { + return Native.getNativeSize(GenericReparseBuffer.class, null); + } + + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "DataBuffer" }); + } + + public GenericReparseBuffer() { + super(); + } + + public GenericReparseBuffer(Pointer memory) { + super(memory); + read(); + } + + public GenericReparseBuffer(String DataBuffer) { + super(); + this.DataBuffer = DataBuffer.getBytes(); + write(); + } + } + + /** + * The REPARSE_DATA_BUFFER structure contains reparse point data for a Microsoft reparse point. + * (Third-party reparse point owners must use the REPARSE_GUID_DATA_BUFFER structure instead.) + */ + public static class REPARSE_DATA_BUFFER extends Structure { + + public static class ByReference extends REPARSE_DATA_BUFFER implements Structure.ByReference { + public ByReference() { + } + + public ByReference(Pointer memory) { + super(memory); + } + } + + /** + * Reparse point tag. Must be a Microsoft reparse point tag. + */ + public int ReparseTag = 0; + + /** + * Size, in bytes, of the reparse data in the DataBuffer member. + */ + public short ReparseDataLength = 0; + + /** + * Length, in bytes, of the unparsed portion of the file name pointed to by the FileName member of the associated file object. + * For more information about the FileName member, see FILE_OBJECT. This member is only valid for create operations when the + * I/O fails with STATUS_REPARSE. For all other purposes, such as setting or querying a reparse point for the reparse data, + * this member is treated as reserved. + */ + public short Reserved = 0; + + public static class REPARSE_UNION extends Union { + public static class ByReference extends REPARSE_UNION implements Structure.ByReference { + + } + + public REPARSE_UNION() { + super(); + } + + public REPARSE_UNION(Pointer memory) { + super(memory); + } + + public SymbolicLinkReparseBuffer symLinkReparseBuffer; + public MountPointReparseBuffer mountPointReparseBuffer; + public GenericReparseBuffer genericReparseBuffer; + } + + public REPARSE_UNION u; + + public static int sizeOf() { + return Native.getNativeSize(REPARSE_DATA_BUFFER.class, null); + } + + /** + * @return size of the structure considering the ReparseDataLength size + */ + public int getSize() { + return REPARSE_BUFFER_HEADER_SIZE + ReparseDataLength; + } + + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "ReparseTag", "ReparseDataLength", "Reserved", "u" }); + } + + public REPARSE_DATA_BUFFER() { + super(); + } + + public REPARSE_DATA_BUFFER(int ReparseTag, short Reserved) { + super(); + this.ReparseTag = ReparseTag; + this.Reserved = Reserved; + this.ReparseDataLength = 0; + write(); + } + + public REPARSE_DATA_BUFFER(int ReparseTag, short Reserved, SymbolicLinkReparseBuffer symLinkReparseBuffer) { + super(); + this.ReparseTag = ReparseTag; + this.Reserved = Reserved; + this.ReparseDataLength = (short) symLinkReparseBuffer.size(); + this.u.setType(SymbolicLinkReparseBuffer.class); + this.u.symLinkReparseBuffer = symLinkReparseBuffer; + write(); + } + + public REPARSE_DATA_BUFFER(Pointer memory) { + super(memory); + read(); + } + + @Override + public void read() { + super.read(); + // Set structure value based on ReparseTag and then re-read the union. + switch(ReparseTag) { + default: + u.setType(GenericReparseBuffer.class); + break; + case WinNT.IO_REPARSE_TAG_MOUNT_POINT: + u.setType(MountPointReparseBuffer.class); + break; + case WinNT.IO_REPARSE_TAG_SYMLINK: + u.setType(SymbolicLinkReparseBuffer.class); + break; + } + u.read(); + } + } +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/NTSecApi.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/NTSecApi.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/NTSecApi.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/NTSecApi.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,18 +1,28 @@ /* 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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 java.util.Arrays; import java.util.List; import com.sun.jna.Memory; @@ -21,44 +31,45 @@ import com.sun.jna.Union; import com.sun.jna.platform.win32.WinNT.LARGE_INTEGER; import com.sun.jna.platform.win32.WinNT.PSID; -import com.sun.jna.win32.StdCallLibrary; /** * Ported from NTSecApi.h * Windows SDK 6.0A. * @author dblock[at]dblock.org */ -public interface NTSecApi extends StdCallLibrary { - +public interface NTSecApi { + /** - * The LSA_UNICODE_STRING structure is used by various Local Security Authority (LSA) + * The LSA_UNICODE_STRING structure is used by various Local Security Authority (LSA) * functions to specify a Unicode string. */ public static class LSA_UNICODE_STRING extends Structure { public static class ByReference extends LSA_UNICODE_STRING implements Structure.ByReference { } - + + public static final List FIELDS = createFieldsOrder("Length", "MaximumLength", "Buffer"); /** - * Specifies the length, in bytes, of the string pointed to by the Buffer member, + * Specifies the length, in bytes, of the string pointed to by the Buffer member, * not including the terminating null character, if any. */ public short Length; /** - * Specifies the total size, in bytes, of the memory allocated for Buffer. Up to + * Specifies the total size, in bytes, of the memory allocated for Buffer. Up to * MaximumLength bytes can be written into the buffer without trampling memory. */ public short MaximumLength; /** - * Pointer to a wide character string. Note that the strings returned by the + * Pointer to a wide character string. Note that the strings returned by the * various LSA functions might not be null terminated. */ public Pointer Buffer; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "Length", "MaximumLength", "Buffer" }); + + @Override + protected List getFieldOrder() { + return FIELDS; } - + /** * String representation of the buffer. * @return @@ -79,14 +90,14 @@ * Pointer to an LSA_UNICODE_STRING. */ public static class PLSA_UNICODE_STRING { - public static class ByReference extends PLSA_UNICODE_STRING + public static class ByReference extends PLSA_UNICODE_STRING implements Structure.ByReference { } - + public LSA_UNICODE_STRING.ByReference s; } - + /** * Record contains an included top-level name. */ @@ -101,25 +112,32 @@ int ForestTrustDomainInfo = 2; public static class LSA_FOREST_TRUST_DOMAIN_INFO extends Structure { + public static final List FIELDS = createFieldsOrder("Sid", "DnsName", "NetbiosName"); + public PSID.ByReference Sid; public LSA_UNICODE_STRING DnsName; public LSA_UNICODE_STRING NetbiosName; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "Sid", "DnsName", "NetbiosName" }); + + @Override + protected List getFieldOrder() { + return FIELDS; } } - + public static class LSA_FOREST_TRUST_BINARY_DATA extends Structure { + public static final List FIELDS = createFieldsOrder("Length", "Buffer"); + public int Length; public Pointer Buffer; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "Length", "Buffer" }); + + @Override + protected List getFieldOrder() { + return FIELDS; } } - - public static class LSA_FOREST_TRUST_RECORD extends Structure { - + + public static class LSA_FOREST_TRUST_RECORD extends Structure { + public static class ByReference extends LSA_FOREST_TRUST_RECORD implements Structure.ByReference { } @@ -128,19 +146,20 @@ public static class ByReference extends UNION implements Structure.ByReference { } - + public LSA_UNICODE_STRING TopLevelName; public LSA_FOREST_TRUST_DOMAIN_INFO DomainInfo; public LSA_FOREST_TRUST_BINARY_DATA Data; } - + + public static final List FIELDS = createFieldsOrder("Flags", "ForestTrustType", "Time", "u"); /** * Flags that control the behavior of the operation. */ public int Flags; - + /** - * LSA_FOREST_TRUST_RECORD_TYPE enumeration that indicates the type of the record. + * LSA_FOREST_TRUST_RECORD_TYPE enumeration that indicates the type of the record. * The following table shows the possible values. * ForestTrustTopLevelName * Record contains an included top-level name. @@ -153,19 +172,21 @@ */ public int ForestTrustType; public LARGE_INTEGER Time; - + /** - * Data type depending on ForestTrustType. + * Data type depending on ForestTrustType. */ public UNION u; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "Flags", "ForestTrustType", "Time", "u" }); + + @Override + protected List getFieldOrder() { + return FIELDS; } - + + @Override public void read() { super.read(); - + switch(ForestTrustType) { case NTSecApi.ForestTrustTopLevelName: case NTSecApi.ForestTrustTopLevelNameEx: @@ -178,44 +199,49 @@ u.setType(LSA_FOREST_TRUST_BINARY_DATA.class); break; } - + u.read(); } } - + public static class PLSA_FOREST_TRUST_RECORD extends Structure { public static class ByReference extends PLSA_FOREST_TRUST_RECORD implements Structure.ByReference { - + } - + + public static final List FIELDS = createFieldsOrder("tr"); + public LSA_FOREST_TRUST_RECORD.ByReference tr; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "tr" }); + + @Override + protected List getFieldOrder() { + return FIELDS; } } - + public static class LSA_FOREST_TRUST_INFORMATION extends Structure { - + public static class ByReference extends LSA_FOREST_TRUST_INFORMATION implements Structure.ByReference { - + } - + + public static final List FIELDS = createFieldsOrder("RecordCount", "Entries"); /** - * Number of LSA_FOREST_TRUST_RECORD structures in the array pointed to by the + * Number of LSA_FOREST_TRUST_RECORD structures in the array pointed to by the * Entries member. */ public int RecordCount; /** - * Pointer to a pointer to an array of LSA_FOREST_TRUST_RECORD structures, + * Pointer to a pointer to an array of LSA_FOREST_TRUST_RECORD structures, * each of which contains one piece of forest trust information. */ public PLSA_FOREST_TRUST_RECORD.ByReference Entries; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "RecordCount", "Entries" }); + @Override + protected List getFieldOrder() { + return FIELDS; } - + /** * Get an array of LSA_FOREST_TRUST_RECORD entries. * @return @@ -226,19 +252,21 @@ } } /** - * The LSA_FOREST_TRUST_INFORMATION structure contains Local Security Authority + * The LSA_FOREST_TRUST_INFORMATION structure contains Local Security Authority * forest trust information. */ public static class PLSA_FOREST_TRUST_INFORMATION extends Structure { - + public static class ByReference extends PLSA_FOREST_TRUST_INFORMATION implements Structure.ByReference { - + } + public static final List FIELDS = createFieldsOrder("fti"); public LSA_FOREST_TRUST_INFORMATION.ByReference fti; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "fti" }); + + @Override + protected List getFieldOrder() { + return FIELDS; } } } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/NTStatus.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/NTStatus.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/NTStatus.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/NTStatus.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; @@ -85,5 +96,14 @@ // STATUS_ABANDONED_WAIT_63 // int STATUS_ABANDONED_WAIT_63 = 0x000000BF; + + // + // MessageId: STATUS_INVALID_OWNER + // + // MessageText: + // + // Indicates a particular Security ID may not be assigned as the owner of an object. + // + int STATUS_INVALID_OWNER = 0xC000005A; } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/OaIdl.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/OaIdl.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/OaIdl.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/OaIdl.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,17 +1,38 @@ /* - * + * 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 java.util.Arrays; import java.util.List; import com.sun.jna.IntegerType; +import com.sun.jna.Memory; import com.sun.jna.NativeLong; import com.sun.jna.Pointer; import com.sun.jna.Structure; import com.sun.jna.Union; import com.sun.jna.platform.win32.BaseTSD.ULONG_PTR; +import com.sun.jna.platform.win32.COM.COMUtils; +import com.sun.jna.platform.win32.COM.Dispatch; import com.sun.jna.platform.win32.Guid.GUID; import com.sun.jna.platform.win32.Variant.VARIANT; import com.sun.jna.platform.win32.Variant.VariantArg; @@ -32,14 +53,42 @@ import com.sun.jna.platform.win32.WinDef.USHORT; import com.sun.jna.platform.win32.WinDef.WORD; import com.sun.jna.platform.win32.COM.TypeComp; +import com.sun.jna.platform.win32.COM.Unknown; +import static com.sun.jna.platform.win32.Variant.VT_BOOL; +import static com.sun.jna.platform.win32.Variant.VT_BSTR; +import static com.sun.jna.platform.win32.Variant.VT_CY; +import static com.sun.jna.platform.win32.Variant.VT_DATE; +import static com.sun.jna.platform.win32.Variant.VT_DECIMAL; +import static com.sun.jna.platform.win32.Variant.VT_DISPATCH; +import static com.sun.jna.platform.win32.Variant.VT_ERROR; +import static com.sun.jna.platform.win32.Variant.VT_I1; +import static com.sun.jna.platform.win32.Variant.VT_I2; +import static com.sun.jna.platform.win32.Variant.VT_I4; +import static com.sun.jna.platform.win32.Variant.VT_INT; +import static com.sun.jna.platform.win32.Variant.VT_R4; +import static com.sun.jna.platform.win32.Variant.VT_R8; +import static com.sun.jna.platform.win32.Variant.VT_RECORD; +import static com.sun.jna.platform.win32.Variant.VT_UI1; +import static com.sun.jna.platform.win32.Variant.VT_UI2; +import static com.sun.jna.platform.win32.Variant.VT_UI4; +import static com.sun.jna.platform.win32.Variant.VT_UINT; +import static com.sun.jna.platform.win32.Variant.VT_UNKNOWN; +import static com.sun.jna.platform.win32.Variant.VT_VARIANT; import com.sun.jna.ptr.ByReference; +import com.sun.jna.ptr.PointerByReference; +import java.io.Closeable; +import java.util.Date; -// TODO: Auto-generated Javadoc /** * The Interface OaIdl. */ 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 + public static final long DATE_OFFSET = new Date(1899 - 1900, 12 - 1, 30, 0, 0, 0).getTime(); + /** * The Class EXCEPINFO. */ @@ -52,6 +101,10 @@ Structure.ByReference { } + public static final List FIELDS = createFieldsOrder("wCode", "wReserved", "bstrSource", + "bstrDescription", "bstrHelpFile", "dwHelpContext", + "pvReserved", "pfnDeferredFillIn", "scode"); + /** The w code. */ public WORD wCode; @@ -83,11 +136,12 @@ * Instantiates a new excepinfo. */ public EXCEPINFO() { + super(); } /** * Instantiates a new excepinfo. - * + * * @param p * the p */ @@ -95,21 +149,14 @@ super(p); } - /* - * (non-Javadoc) - * - * @see com.sun.jna.Structure#getFieldOrder() - */ @Override - protected List getFieldOrder() { - return Arrays - .asList(new String[] { "wCode", "wReserved", "bstrSource", - "bstrDescription", "bstrHelpFile", "dwHelpContext", - "pvReserved", "pfnDeferredFillIn", "scode" }); + protected List getFieldOrder() { + return FIELDS; } } public static class VARIANT_BOOL extends IntegerType { + private static final long serialVersionUID = 1L; public static final int SIZE = 2; public VARIANT_BOOL() { @@ -119,9 +166,18 @@ public VARIANT_BOOL(long value) { super(2, value); } + + public VARIANT_BOOL(boolean value) { + this(value ? 0xFFFF : 0x0000); + } + + public boolean booleanValue() { + return shortValue() != 0x0000; + } } public static class _VARIANT_BOOL extends VARIANT_BOOL { + private static final long serialVersionUID = 1L; public _VARIANT_BOOL() { this(0); @@ -171,27 +227,65 @@ } public static class DATE extends Structure { + private final static long MICRO_SECONDS_PER_DAY = 24L * 60L * 60L * 1000L; + public static class ByReference extends DATE implements Structure.ByReference { } + public static final List FIELDS = createFieldsOrder("date"); public double date; public DATE() { + super(); } public DATE(double date) { this.date = date; } - - /* - * (non-Javadoc) - * - * @see com.sun.jna.Structure#getFieldOrder() - */ + + public DATE(Date javaDate) { + setFromJavaDate(javaDate); + } + + public Date getAsJavaDate() { + long days = (((long) this.date) * MICRO_SECONDS_PER_DAY) + DATE_OFFSET; + double timePart = 24 * Math.abs(this.date - ((long) this.date)); + int hours = (int) timePart; + timePart = 60 * (timePart - ((int) timePart)); + int minutes = (int) timePart; + timePart = 60 * (timePart - ((int) timePart)); + int seconds = (int) timePart; + timePart = 1000 * (timePart - ((int) timePart)); + int milliseconds = (int) timePart; + + Date baseDate = new Date(days); + baseDate.setHours(hours); + baseDate.setMinutes(minutes); + baseDate.setSeconds(seconds); + baseDate.setTime(baseDate.getTime() + milliseconds); + return baseDate; + } + + public void setFromJavaDate(Date javaDate) { + double msSinceOrigin = javaDate.getTime() - DATE_OFFSET; + double daysAsFract = msSinceOrigin / MICRO_SECONDS_PER_DAY; + + Date dayDate = new Date(javaDate.getTime()); + dayDate.setHours(0); + dayDate.setMinutes(0); + dayDate.setSeconds(0); + dayDate.setTime(dayDate.getTime() / 1000 * 1000); // Clear milliseconds + + double integralPart = Math.floor(daysAsFract); + double fractionalPart = Math.signum(daysAsFract) * ((javaDate.getTime() - dayDate.getTime()) / (24d * 60 * 60 * 1000)); + + this.date = integralPart + fractionalPart; + } + @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "date" }); + protected List getFieldOrder() { + return FIELDS; } } @@ -199,6 +293,8 @@ * The Class DISPID. */ public static class DISPID extends LONG { + private static final long serialVersionUID = 1L; + public DISPID() { this(0); } @@ -228,6 +324,8 @@ } public static class MEMBERID extends DISPID { + private static final long serialVersionUID = 1L; + public MEMBERID() { this(0); } @@ -362,9 +460,11 @@ } } + public static final List FIELDS = createFieldsOrder("value"); public int value; public TYPEKIND() { + super(); } public TYPEKIND(int value) { @@ -396,8 +496,8 @@ public static final int TKIND_MAX = TYPEKIND.TKIND_UNION + 1; @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "value" }); + protected List getFieldOrder() { + return FIELDS; } }; @@ -406,9 +506,12 @@ Structure.ByReference { } + public static final List FIELDS = createFieldsOrder("value"); + public int value; public DESCKIND() { + super(); } public DESCKIND(int value) { @@ -434,16 +537,55 @@ public static final int DESCKIND_MAX = DESCKIND.DESCKIND_IMPLICITAPPOBJ + 1; @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "value" }); + protected List getFieldOrder() { + return FIELDS; } }; - public static class SAFEARRAY extends Structure { + /** + * Implementation of SAFEARRAY. Implements Closable, which in this case + * delegates to destroy, to free native memory on close. + * + *

    VARTYPE for the SAFEARRAY can be:

    + * + *
      + *
    • VT_BOOL
    • + *
    • VT_BSTR
    • + *
    • VT_CY
    • + *
    • VT_DATE
    • + *
    • VT_DECIMAL
    • + *
    • VT_DISPATCH
    • + *
    • VT_ERROR
    • + *
    • VT_I1
    • + *
    • VT_I2
    • + *
    • VT_I4
    • + *
    • VT_INT
    • + *
    • VT_R4
    • + *
    • VT_R8
    • + *
    • VT_RECORD
    • + *
    • VT_UI1
    • + *
    • VT_UI2
    • + *
    • VT_UI4
    • + *
    • VT_UINT
    • + *
    • VT_UNKNOWN
    • + *
    • VT_VARIANT
    • + *
    + * + *

    General comment: All indices in the helper methods use java int.

    + * + *

    The native type for the indices is LONG, which is defined as:

    + * + *
    A 32-bit signed integer. The range is �2147483648 through 2147483647 decimal.
    + */ + public static class SAFEARRAY extends Structure implements Closeable { + public static class ByReference extends SAFEARRAY implements Structure.ByReference { } + public static final List FIELDS = createFieldsOrder( + "cDims", "fFeatures", "cbElements", "cLocks", "pvData", "rgsabound"); + public USHORT cDims; public USHORT fFeatures; public ULONG cbElements; @@ -454,6 +596,7 @@ public SAFEARRAYBOUND[] rgsabound = { new SAFEARRAYBOUND() }; public SAFEARRAY() { + super(); } public SAFEARRAY(Pointer pointer) { @@ -462,9 +605,436 @@ } @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "cDims", "fFeatures", - "cbElements", "cLocks", "pvData", "rgsabound" }); + public void read() { + super.read(); + rgsabound = (SAFEARRAYBOUND[]) rgsabound[0].toArray(cDims.intValue()); + } + + @Override + protected List getFieldOrder() { + return FIELDS; + } + + /** + * Create a SAFEARRAY with supplied VARIANT as element type. + * + *

    + * This helper creates a basic SAFEARRAY with a base type of VT_VARIANT. + * The array will have as many dimensions as parameters are passed in. + * The lowerbound for each dimension is set to zero, the count to the + * parameter value.

    + * + * @param size array of dimension size + * @return SAFEARRAYWrapper or {@code NULL} if creation fails. + */ + public static SAFEARRAY createSafeArray(int... size) { + return createSafeArray(new WTypes.VARTYPE(Variant.VT_VARIANT), size); + } + + /** + * Create a SAFEARRAY with supplied element type. + * + *

    + * The array will have as many dimensions as parameters are passed in. + * The lowerbound for each dimension is set to zero, the count to the + * parameter value.

    + * + * @param vartype type of array contents (see Variant.VT_* constants) + * @param size array of dimension size + * @return SAFEARRAYWrapper or {@code NULL} if creation fails. + */ + public static SAFEARRAY createSafeArray(VARTYPE vartype, int... size) { + OaIdl.SAFEARRAYBOUND[] rgsabound = (OaIdl.SAFEARRAYBOUND[]) new OaIdl.SAFEARRAYBOUND().toArray(size.length); + for (int i = 0; i < size.length; i++) { + rgsabound[i].lLbound = new WinDef.LONG(0); + rgsabound[i].cElements = new WinDef.ULONG(size[size.length - i - 1]); + } + SAFEARRAY.ByReference data = OleAuto.INSTANCE.SafeArrayCreate(vartype, new WinDef.UINT(size.length), rgsabound); + return data; + } + + /** + * Set value at {@code indices} in {@code array} to arg. + * + *

    + * The supplied argument is copied into the array. If the value is no + * longer needed, it needs to be freed if not handled automatically.

    + * + * @param indices the index, order follows java/C convention + * @param arg the arg + */ + public void putElement(Object arg, int... indices) { + WinDef.LONG[] paramIndices = new WinDef.LONG[indices.length]; + for (int i = 0; i < indices.length; i++) { + paramIndices[i] = new WinDef.LONG(indices[indices.length - i - 1]); + } + + WinNT.HRESULT hr; + Memory mem; + switch (getVarType().intValue()) { + case VT_BOOL: + mem = new Memory(2); + if(arg instanceof Boolean) { + mem.setShort(0, (short) (((Boolean) arg) ? 0xFFFF : 0) ); + } else { + mem.setShort(0, (short) (((Number) arg).intValue() > 0 ? 0xFFFF : 0)); + } + hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, mem); + COMUtils.checkRC(hr); + break; + case VT_UI1: + case VT_I1: + mem = new Memory(1); + mem.setByte(0, ((Number) arg).byteValue()); + hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, mem); + COMUtils.checkRC(hr); + break; + case VT_UI2: + case VT_I2: + mem = new Memory(2); + mem.setShort(0, ((Number) arg).shortValue()); + hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, mem); + COMUtils.checkRC(hr); + break; + case VT_UI4: + case VT_UINT: + case VT_I4: + case VT_INT: + mem = new Memory(4); + mem.setInt(0, ((Number) arg).intValue()); + hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, mem); + COMUtils.checkRC(hr); + break; + case VT_ERROR: + mem = new Memory(4); + mem.setInt(0, ((Number) arg).intValue()); + hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, mem); + COMUtils.checkRC(hr); + break; + case VT_R4: + mem = new Memory(4); + mem.setFloat(0, ((Number) arg).floatValue()); + hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, mem); + COMUtils.checkRC(hr); + break; + case VT_R8: + mem = new Memory(8); + mem.setDouble(0, ((Number) arg).doubleValue()); + hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, mem); + COMUtils.checkRC(hr); + break; + case VT_DATE: + mem = new Memory(8); + mem.setDouble(0, ((DATE) arg).date); + hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, mem); + COMUtils.checkRC(hr); + break; + case VT_BSTR: + if(arg instanceof String) { + BSTR bstr = OleAuto.INSTANCE.SysAllocString((String) arg); + hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, bstr.getPointer()); + OleAuto.INSTANCE.SysFreeString(bstr); + COMUtils.checkRC(hr); + } else { + hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, ((BSTR) arg).getPointer()); + COMUtils.checkRC(hr); + } + break; + case VT_VARIANT: + hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, ((VARIANT) arg).getPointer()); + COMUtils.checkRC(hr); + break; + case VT_UNKNOWN: + hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, ((Unknown) arg).getPointer()); + COMUtils.checkRC(hr); + break; + case VT_DISPATCH: + hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, ((Dispatch) arg).getPointer()); + COMUtils.checkRC(hr); + break; + case VT_CY: + hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, ((CURRENCY) arg).getPointer()); + COMUtils.checkRC(hr); + break; + case VT_DECIMAL: + hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, ((DECIMAL) arg).getPointer()); + COMUtils.checkRC(hr); + break; + case VT_RECORD: + default: + throw new IllegalStateException("Can't parse array content - type not supported: " + getVarType().intValue()); + } + } + + /** + * Retrieve the value at the referenced index from the SAFEARRAY. + * + *

    The function creates a copy of the value. The values are + * allocated with native functions and need to be freed accordingly.

    + * + * @param indices the index, order follows java/C convention + * @return the variant + */ + public Object getElement(int... indices) { + WinDef.LONG[] paramIndices = new WinDef.LONG[indices.length]; + for (int i = 0; i < indices.length; i++) { + paramIndices[i] = new WinDef.LONG(indices[indices.length - i - 1]); + } + + Object result; + WinNT.HRESULT hr; + Memory mem; + PointerByReference pbr; + switch (getVarType().intValue()) { + case VT_BOOL: + mem = new Memory(2); + hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, mem); + COMUtils.checkRC(hr); + result = mem.getShort(0) != 0; + break; + case VT_UI1: + case VT_I1: + mem = new Memory(1); + hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, mem); + COMUtils.checkRC(hr); + result = mem.getByte(0); + break; + case VT_UI2: + case VT_I2: + mem = new Memory(2); + hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, mem); + COMUtils.checkRC(hr); + result = mem.getShort(0); + break; + case VT_UI4: + case VT_UINT: + case VT_I4: + case VT_INT: + mem = new Memory(4); + hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, mem); + COMUtils.checkRC(hr); + result = mem.getInt(0); + break; + case VT_ERROR: + mem = new Memory(4); + hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, mem); + COMUtils.checkRC(hr); + result = new SCODE(mem.getInt(0)); + break; + case VT_R4: + mem = new Memory(4); + hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, mem); + COMUtils.checkRC(hr); + result = mem.getFloat(0); + break; + case VT_R8: + mem = new Memory(8); + hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, mem); + COMUtils.checkRC(hr); + result = mem.getDouble(0); + break; + case VT_DATE: + mem = new Memory(8); + hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, mem); + COMUtils.checkRC(hr); + result = new DATE(mem.getDouble(0)); + break; + case VT_BSTR: + pbr = new PointerByReference(); + hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, pbr.getPointer()); + COMUtils.checkRC(hr); + BSTR bstr = new BSTR(pbr.getValue()); + result = bstr.getValue(); + OleAuto.INSTANCE.SysFreeString(bstr); + break; + case VT_VARIANT: + VARIANT holder = new Variant.VARIANT(); + hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, holder.getPointer()); + COMUtils.checkRC(hr); + result = holder; + break; + case VT_UNKNOWN: + pbr = new PointerByReference(); + hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, pbr.getPointer()); + COMUtils.checkRC(hr); + result = new Unknown(pbr.getValue()); + break; + case VT_DISPATCH: + pbr = new PointerByReference(); + hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, pbr.getPointer()); + COMUtils.checkRC(hr); + result = new Dispatch(pbr.getValue()); + break; + case VT_CY: + CURRENCY currency = new CURRENCY(); + hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, currency.getPointer()); + COMUtils.checkRC(hr); + result = currency; + break; + case VT_DECIMAL: + DECIMAL decimal = new DECIMAL(); + hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, decimal.getPointer()); + COMUtils.checkRC(hr); + result = decimal; + break; + case VT_RECORD: + default: + throw new IllegalStateException("Can't parse array content - type not supported: " + getVarType().intValue()); + } + + return result; + } + + /** + * Retrieve pointer to data element from array. + * + *

    + * Caller is responsible for (un)locking the array via + * {@link OleAuto#SafeArrayLock} and {@link OleAuto#SafeArrayUnlock} or + * the helper methods: {@link SAFEARRAY#lock} and + * {@link SAFEARRAY#unlock}.

    + * + * @param indices the index, order follows java/C convention + * @return the pointer to the data element + */ + public Pointer ptrOfIndex(int... indices) { + WinDef.LONG[] paramIndices = new WinDef.LONG[indices.length]; + for (int i = 0; i < indices.length; i++) { + paramIndices[i] = new WinDef.LONG(indices[indices.length - i - 1]); + } + PointerByReference pbr = new PointerByReference(); + WinNT.HRESULT hr = OleAuto.INSTANCE.SafeArrayPtrOfIndex(this, paramIndices, pbr); + COMUtils.checkRC(hr); + return pbr.getValue(); + } + + /** + * Destroy the underlying SAFEARRAY and free memory + */ + public void destroy() { + WinNT.HRESULT res = OleAuto.INSTANCE.SafeArrayDestroy(this); + COMUtils.checkRC(res); + } + + /** + * Implemented to satisfy Closeable interface, delegates to destroy. + */ + public void close() { + destroy(); + } + + /** + * Retrieve lower bound for the selected dimension. + * + *

    As in the all the accessor functions, that index is converted to + * java conventions.

    + * + * @param dimension zerobased index + * @return lower bound for the selected dimension + */ + public int getLBound(int dimension) { + int targetDimension = getDimensionCount() - dimension; + WinDef.LONGByReference bound = new WinDef.LONGByReference(); + WinNT.HRESULT res = OleAuto.INSTANCE.SafeArrayGetLBound(this, new WinDef.UINT(targetDimension), bound); + COMUtils.checkRC(res); + return bound.getValue().intValue(); + } + + /** + * Retrieve upper bound for the selected dimension. + * + *

    As in the all the accessor functions, that index is converted to + * java conventions.

    + * + * @param dimension zerobased index + * @return upper bound for the selected dimension + */ + public int getUBound(int dimension) { + int targetDimension = getDimensionCount() - dimension; + WinDef.LONGByReference bound = new WinDef.LONGByReference(); + WinNT.HRESULT res = OleAuto.INSTANCE.SafeArrayGetUBound(this, new WinDef.UINT(targetDimension), bound); + COMUtils.checkRC(res); + return bound.getValue().intValue(); + } + + /** + * Return number of dimensions of the SAFEARRAY + * + * @return number of dimensions of the SAFEARRAY + */ + public int getDimensionCount() { + return OleAuto.INSTANCE.SafeArrayGetDim(this).intValue(); + } + + /** + * Lock array and retrieve pointer to data + * + * @return Pointer to arraydata + */ + public Pointer accessData() { + PointerByReference pbr = new PointerByReference(); + WinNT.HRESULT hr = OleAuto.INSTANCE.SafeArrayAccessData(this, pbr); + COMUtils.checkRC(hr); + return pbr.getValue(); + } + + /** + * Unlock array and invalidate the pointer retrieved via + * SafeArrayAccessData + */ + public void unaccessData() { + WinNT.HRESULT hr = OleAuto.INSTANCE.SafeArrayUnaccessData(this); + COMUtils.checkRC(hr); + } + + /** + * Increments the lock count of an array, and places a pointer to the + * array data in pvData of the array descriptor. + */ + public void lock() { + WinNT.HRESULT res = OleAuto.INSTANCE.SafeArrayLock(this); + COMUtils.checkRC(res); + } + + /** + * Decrements the lock count of an array so it can be freed or resized + */ + public void unlock() { + WinNT.HRESULT res = OleAuto.INSTANCE.SafeArrayUnlock(this); + COMUtils.checkRC(res); + } + + /** + * Changes the right-most (least significant) bound of the specified + * safe array. + * + * @param cElements + * @param lLbound + */ + public void redim(int cElements, int lLbound) { + WinNT.HRESULT res = OleAuto.INSTANCE.SafeArrayRedim(this, new OaIdl.SAFEARRAYBOUND(cElements, lLbound)); + COMUtils.checkRC(res); + } + + /** + * Return VARTYPE of the SAFEARRAY + * + * @return VARTYPE of the SAFEARRAY + */ + public VARTYPE getVarType() { + WTypes.VARTYPEByReference resultHolder = new WTypes.VARTYPEByReference(); + WinNT.HRESULT res = OleAuto.INSTANCE.SafeArrayGetVartype(this, resultHolder); + COMUtils.checkRC(res); + return resultHolder.getValue(); + } + + /** + * Get size of one element in bytes + * + * @return element size in bytes + */ + public long getElemsize() { + return OleAuto.INSTANCE.SafeArrayGetElemsize(this).longValue(); } } @@ -473,11 +1043,13 @@ Structure.ByReference { } - public ULONG cElements; + public static final List FIELDS = createFieldsOrder("cElements", "lLbound"); + public ULONG cElements; public LONG lLbound; public SAFEARRAYBOUND() { + super(); } public SAFEARRAYBOUND(Pointer pointer) { @@ -492,8 +1064,8 @@ } @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "cElements", "lLbound" }); + protected List getFieldOrder() { + return FIELDS; } } @@ -516,6 +1088,8 @@ } public static class _CURRENCY extends Structure { + public static final List FIELDS = createFieldsOrder("Lo", "Hi"); + public ULONG Lo; public LONG Hi; @@ -529,30 +1103,19 @@ } @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "Lo", "Hi" }); + protected List getFieldOrder() { + return FIELDS; } } } public static class DECIMAL extends Structure { + public static final List FIELDS = createFieldsOrder("wReserved", "decimal1", "Hi32", "decimal2"); public static class ByReference extends DECIMAL implements Structure.ByReference { }; - public DECIMAL() { - super(); - } - - public DECIMAL(Pointer pointer) { - super(pointer); - } - - public short wReserved; - public _DECIMAL1 decimal1; - public NativeLong Hi32; - public _DECIMAL2 decimal2; public static class _DECIMAL1 extends Union { @@ -560,7 +1123,6 @@ public _DECIMAL1_DECIMAL decimal1_DECIMAL; public _DECIMAL1() { - super(); this.setType("signscale"); } @@ -571,6 +1133,7 @@ } public static class _DECIMAL1_DECIMAL extends Structure { + public static final List FIELDS = createFieldsOrder("scale", "sign"); public BYTE scale; public BYTE sign; @@ -583,14 +1146,13 @@ } @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "scale", "sign" }); + protected List getFieldOrder() { + return FIELDS; } } } public static class _DECIMAL2 extends Union { - public ULONGLONG Lo64; public _DECIMAL2_DECIMAL decimal2_DECIMAL; @@ -605,6 +1167,8 @@ } public static class _DECIMAL2_DECIMAL extends Structure { + public static final List FIELDS = createFieldsOrder("Lo32", "Mid32"); + public BYTE Lo32; public BYTE Mid32; @@ -617,16 +1181,28 @@ } @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "Lo32", "Mid32" }); + protected List getFieldOrder() { + return FIELDS; } } } + public short wReserved; + public _DECIMAL1 decimal1; + public NativeLong Hi32; + public _DECIMAL2 decimal2; + + public DECIMAL() { + super(); + } + + public DECIMAL(Pointer pointer) { + super(pointer); + } + @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "wReserved", "decimal1", - "Hi32", "decimal2" }); + protected List getFieldOrder() { + return FIELDS; } } @@ -635,9 +1211,11 @@ Structure.ByReference { } - public int value; + public static final List FIELDS = createFieldsOrder("value"); + public int value; public SYSKIND() { + super(); } public SYSKIND(int value) { @@ -655,8 +1233,8 @@ public static final int SYS_WIN64 = SYSKIND.SYS_MAC + 1; @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "value" }); + protected List getFieldOrder() { + return FIELDS; } }; @@ -665,9 +1243,11 @@ Structure.ByReference { } + public static final List FIELDS = createFieldsOrder("value"); public int value; public LIBFLAGS() { + super(); } public LIBFLAGS(int value) { @@ -685,8 +1265,8 @@ public static final int LIBFLAG_FHASDISKIMAGE = 0x8; @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "value" }); + protected List getFieldOrder() { + return FIELDS; } }; @@ -695,6 +1275,7 @@ Structure.ByReference { public ByReference() { + super(); } public ByReference(Pointer pointer) { @@ -703,6 +1284,9 @@ } }; + public static final List FIELDS = createFieldsOrder("guid", "lcid", "syskind", + "wMajorVerNum", "wMinorVerNum", "wLibFlags"); + public GUID guid; public LCID lcid; public SYSKIND syskind; @@ -720,9 +1304,8 @@ } @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "guid", "lcid", "syskind", - "wMajorVerNum", "wMinorVerNum", "wLibFlags" }); + protected List getFieldOrder() { + return FIELDS; } } @@ -769,6 +1352,11 @@ Structure.ByReference { }; + public static final List FIELDS = createFieldsOrder("memid", "lprgscode", + "lprgelemdescParam", "funckind", "invkind", "callconv", + "cParams", "cParamsOpt", "oVft", "cScodes", "elemdescFunc", + "wFuncFlags"); + public MEMBERID memid; public ScodeArg.ByReference lprgscode; public ElemDescArg.ByReference lprgelemdescParam; @@ -783,6 +1371,7 @@ public WORD wFuncFlags; public FUNCDESC() { + super(); } public FUNCDESC(Pointer pointer) { @@ -798,10 +1387,7 @@ @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "memid", "lprgscode", - "lprgelemdescParam", "funckind", "invkind", "callconv", - "cParams", "cParamsOpt", "oVft", "cScodes", "elemdescFunc", - "wFuncFlags" }); + return FIELDS; } } @@ -810,9 +1396,12 @@ Structure.ByReference { } + public static final List FIELDS = createFieldsOrder("elemDescArg"); + public ELEMDESC[] elemDescArg = { new ELEMDESC() }; public ElemDescArg() { + super(); } public ElemDescArg(Pointer pointer) { @@ -821,8 +1410,8 @@ } @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "elemDescArg" }); + protected List getFieldOrder() { + return FIELDS; } } @@ -831,9 +1420,12 @@ Structure.ByReference { } + public static final List FIELDS = createFieldsOrder("scodeArg"); + public SCODE[] scodeArg = { new SCODE() }; public ScodeArg() { + super(); } public ScodeArg(Pointer pointer) { @@ -842,8 +1434,8 @@ } @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "scodeArg" }); + protected List getFieldOrder() { + return FIELDS; } } @@ -852,6 +1444,9 @@ Structure.ByReference { }; + public static final List FIELDS = createFieldsOrder("memid", "lpstrSchema", "_vardesc", + "elemdescVar", "wVarFlags", "varkind"); + // / C type : MEMBERID public MEMBERID memid; // / C type : LPOLESTR @@ -883,7 +1478,6 @@ public VARIANT.ByReference lpvarValue; public _VARDESC() { - super(); setType("lpvarValue"); this.read(); } @@ -900,14 +1494,12 @@ * C type : VARIANT* */ public _VARDESC(VARIANT.ByReference lpvarValue) { - super(); this.lpvarValue = lpvarValue; setType("lpvarValue"); } // / @param oInst [case()] public _VARDESC(NativeLong oInst) { - super(); this.oInst = oInst; setType("oInst"); } @@ -924,9 +1516,8 @@ } @Override - protected List getFieldOrder() { - return Arrays.asList("memid", "lpstrSchema", "_vardesc", - "elemdescVar", "wVarFlags", "varkind"); + protected List getFieldOrder() { + return FIELDS; } } @@ -935,6 +1526,7 @@ Structure.ByReference { }; + public static final List FIELDS = createFieldsOrder("tdesc", "_elemdesc"); /** * the type of the element
    * C type : TYPEDESC @@ -991,18 +1583,19 @@ } }; - @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "tdesc", "_elemdesc" }); - } - public ELEMDESC() { + super(); } public ELEMDESC(Pointer pointer) { super(pointer); this.read(); } + + @Override + protected List getFieldOrder() { + return FIELDS; + } } public static class FUNCKIND extends Structure { @@ -1021,9 +1614,12 @@ // / native declaration : line 24 public static final int FUNC_DISPATCH = FUNC_STATIC + 1; + public static final List FIELDS = createFieldsOrder("value"); + public int value; public FUNCKIND() { + super(); } public FUNCKIND(int value) { @@ -1032,8 +1628,8 @@ } @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "value" }); + protected List getFieldOrder() { + return FIELDS; } }; @@ -1042,6 +1638,8 @@ Structure.ByReference { }; + public static final List FIELDS = createFieldsOrder("value"); + // / native declaration : line 30 public static final INVOKEKIND INVOKE_FUNC = new INVOKEKIND(1); // / native declaration : line 31 @@ -1054,6 +1652,7 @@ public int value; public INVOKEKIND() { + super(); } public INVOKEKIND(int value) { @@ -1062,8 +1661,8 @@ } @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "value" }); + protected List getFieldOrder() { + return FIELDS; } }; @@ -1072,6 +1671,8 @@ Structure.ByReference { }; + public static final List FIELDS = createFieldsOrder("value"); + // / native declaration : line 4 public static final int CC_FASTCALL = 0; // / native declaration : line 5 @@ -1106,7 +1707,7 @@ @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "value" }); + return FIELDS; } }; @@ -1124,9 +1725,12 @@ // / native declaration : line 7 public static final int VAR_DISPATCH = VAR_CONST + 1; + public static final List FIELDS = createFieldsOrder("value"); + public int value; public VARKIND() { + super(); } public VARKIND(int value) { @@ -1134,8 +1738,8 @@ } @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "value" }); + protected List getFieldOrder() { + return FIELDS; } }; @@ -1144,23 +1748,6 @@ Structure.ByReference { }; - public _TYPEDESC _typedesc; - - public VARTYPE vt; - - public TYPEDESC() { - this.read(); - } - - public TYPEDESC(Pointer pointer) { - super(pointer); - this.read(); - } - - public TYPEDESC(_TYPEDESC _typedesc, VARTYPE vt) { - this._typedesc = _typedesc; - this.vt = vt; - } public static class _TYPEDESC extends Union { /** @@ -1209,8 +1796,27 @@ } }; - protected List getFieldOrder() { - return Arrays.asList("_typedesc", "vt"); + public static final List FIELDS = createFieldsOrder("_typedesc", "vt"); + public _TYPEDESC _typedesc; + public VARTYPE vt; + + public TYPEDESC() { + this.read(); + } + + public TYPEDESC(Pointer pointer) { + super(pointer); + this.read(); + } + + public TYPEDESC(_TYPEDESC _typedesc, VARTYPE vt) { + this._typedesc = _typedesc; + this.vt = vt; + } + + @Override + protected List getFieldOrder() { + return FIELDS; } } @@ -1219,6 +1825,7 @@ Structure.ByReference { public ByReference() { + super(); } public ByReference(IDLDESC idldesc) { @@ -1226,6 +1833,8 @@ } }; + public static final List FIELDS = createFieldsOrder("dwReserved", "wIDLFlags"); + // / C type : ULONG_PTR public ULONG_PTR dwReserved; public USHORT wIDLFlags; @@ -1241,18 +1850,18 @@ // / @param dwReserved C type : ULONG_PTR public IDLDESC(ULONG_PTR dwReserved, USHORT wIDLFlags) { - super(); this.dwReserved = dwReserved; this.wIDLFlags = wIDLFlags; } @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "dwReserved", "wIDLFlags" }); + protected List getFieldOrder() { + return FIELDS; } } public class ARRAYDESC extends Structure { + public static final List FIELDS = createFieldsOrder("tdescElem", "cDims", "rgbounds"); // / C type : TYPEDESC public TYPEDESC tdescElem; public short cDims; @@ -1271,8 +1880,9 @@ this.read(); } - protected List getFieldOrder() { - return Arrays.asList("tdescElem", "cDims", "rgbounds"); + @Override + protected List getFieldOrder() { + return FIELDS; } /** @@ -1283,9 +1893,7 @@ * [size_is]
    * C type : SAFEARRAYBOUND[1] */ - public ARRAYDESC(TYPEDESC tdescElem, short cDims, - SAFEARRAYBOUND rgbounds[]) { - super(); + public ARRAYDESC(TYPEDESC tdescElem, short cDims, SAFEARRAYBOUND rgbounds[]) { this.tdescElem = tdescElem; this.cDims = cDims; if (rgbounds.length != this.rgbounds.length) @@ -1304,6 +1912,8 @@ Structure.ByReference { }; + public static final List FIELDS = createFieldsOrder("pparamdescex", "wParamFlags"); + // replaced PARAMDESCEX.ByReference with Pointer // because of JNA 4 has a problem with ByReference public Pointer pparamdescex; @@ -1319,9 +1929,8 @@ } @Override - protected List getFieldOrder() { - return Arrays - .asList(new String[] { "pparamdescex", "wParamFlags" }); + protected List getFieldOrder() { + return FIELDS; } } @@ -1330,6 +1939,8 @@ Structure.ByReference { }; + public static final List FIELDS = createFieldsOrder("cBytes", "varDefaultValue"); + public ULONG cBytes; public VariantArg varDefaultValue; @@ -1344,11 +1955,13 @@ @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "cBytes", "varDefaultValue" }); + return FIELDS; } } public static class HREFTYPE extends DWORD { + private static final long serialVersionUID = 1L; + public HREFTYPE() { super(); } @@ -1371,6 +1984,7 @@ getPointer().setInt(0, value.intValue()); } + @Override public HREFTYPE getValue() { return new HREFTYPE(getPointer().getInt(0)); } @@ -1381,6 +1995,13 @@ Structure.ByReference { }; + public static final List FIELDS = createFieldsOrder("guid", "lcid", "dwReserved", "memidConstructor", + "memidDestructor", "lpstrSchema", "cbSizeInstance", + "typekind", "cFuncs", "cVars", "cImplTypes", + "cbSizeVft", "cbAlignment", "wTypeFlags", + "wMajorVerNum", "wMinorVerNum", "tdescAlias", + "idldescType"); + // / C type : GUID public GUID guid; // / C type : LCID @@ -1400,6 +2021,7 @@ public WORD cImplTypes; public WORD cbSizeVft; public WORD cbAlignment; + // The type flags. See TYPEFLAGS_... public WORD wTypeFlags; public WORD wMajorVerNum; public WORD wMinorVerNum; @@ -1417,14 +2039,91 @@ this.read(); } - protected List getFieldOrder() { - return Arrays - .asList("guid", "lcid", "dwReserved", "memidConstructor", - "memidDestructor", "lpstrSchema", "cbSizeInstance", - "typekind", "cFuncs", "cVars", "cImplTypes", - "cbSizeVft", "cbAlignment", "wTypeFlags", - "wMajorVerNum", "wMinorVerNum", "tdescAlias", - "idldescType"); + @Override + protected List getFieldOrder() { + return FIELDS; } + + /** + * A type description that describes an Application object. + */ + public final static int TYPEFLAGS_FAPPOBJECT = 0x1; + + /** + * Instances of the type can be created by ITypeInfo::CreateInstance. + */ + public final static int TYPEFLAGS_FCANCREATE = 0x2; + + /** + * The type is licensed. + */ + public final static int TYPEFLAGS_FLICENSED = 0x4; + + /** + * The type is predefined. The client application should automatically create a single instance of the object + * that has this attribute. The name of the variable that points to the object is the same as the class name of + * the object. + */ + public final static int TYPEFLAGS_FPREDECLID = 0x8; + + /** + * The type should not be displayed to browsers. + */ + public final static int TYPEFLAGS_FHIDDEN = 0x10; + + /** + * The type is a control from which other types will be derived, and should not be displayed to users. + */ + public final static int TYPEFLAGS_FCONTROL = 0x20; + + /** + * The interface supplies both IDispatch and VTBL binding. + */ + public final static int TYPEFLAGS_FDUAL = 0x40; + + /** + * The interface cannot add members at run time. + */ + public final static int TYPEFLAGS_FNONEXTENSIBLE = 0x80; + + /** + * The types used in the interface are fully compatible with Automation, including VTBL binding support. Setting + * dual on an interface sets this flag in addition to TYPEFLAG_FDUAL. Not allowed on dispinterfaces. + */ + public final static int TYPEFLAGS_FOLEAUTOMATION = 0x100; + + /** + * Should not be accessible from macro languages. This flag is intended for system-level types or types that + * type browsers should not display. + */ + public final static int TYPEFLAGS_FRESTRICTED = 0x200; + + /** + * The class supports aggregation. + */ + public final static int TYPEFLAGS_FAGGREGATABLE = 0x400; + + /** + * The type is replaceable. + */ + public final static int TYPEFLAGS_FREPLACEABLE = 0x800; + + /** + * Indicates that the interface derives from IDispatch, either directly or indirectly. This flag is computed. + * There is no Object Description Language for the flag. + */ + public final static int TYPEFLAGS_FDISPATCHABLE = 0x1000; + + /** + * The type has reverse binding. + */ + public final static int TYPEFLAGS_FREVERSEBIND = 0x2000; + + /** + * Interfaces can be marked with this flag to indicate that they will be using a proxy/stub dynamic link + * library. This flag specifies that the typelib proxy should not be unregistered when the typelib is + * unregistered. + */ + public final static int TYPEFLAGS_FPROXY = 0x4000; } } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/OaIdlUtil.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/OaIdlUtil.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/OaIdlUtil.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/OaIdlUtil.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,288 @@ +/* + * 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.Pointer; +import com.sun.jna.platform.win32.OaIdl.DATE; +import com.sun.jna.platform.win32.OaIdl.SAFEARRAY; +import com.sun.jna.platform.win32.Variant.VARIANT; +import static com.sun.jna.platform.win32.Variant.VT_BOOL; +import static com.sun.jna.platform.win32.Variant.VT_BSTR; +import static com.sun.jna.platform.win32.Variant.VT_CY; +import static com.sun.jna.platform.win32.Variant.VT_DATE; +import static com.sun.jna.platform.win32.Variant.VT_DECIMAL; +import static com.sun.jna.platform.win32.Variant.VT_DISPATCH; +import static com.sun.jna.platform.win32.Variant.VT_EMPTY; +import static com.sun.jna.platform.win32.Variant.VT_ERROR; +import static com.sun.jna.platform.win32.Variant.VT_I1; +import static com.sun.jna.platform.win32.Variant.VT_I2; +import static com.sun.jna.platform.win32.Variant.VT_I4; +import static com.sun.jna.platform.win32.Variant.VT_INT; +import static com.sun.jna.platform.win32.Variant.VT_NULL; +import static com.sun.jna.platform.win32.Variant.VT_R4; +import static com.sun.jna.platform.win32.Variant.VT_R8; +import static com.sun.jna.platform.win32.Variant.VT_RECORD; +import static com.sun.jna.platform.win32.Variant.VT_UI1; +import static com.sun.jna.platform.win32.Variant.VT_UI2; +import static com.sun.jna.platform.win32.Variant.VT_UI4; +import static com.sun.jna.platform.win32.Variant.VT_UINT; +import static com.sun.jna.platform.win32.Variant.VT_UNKNOWN; +import static com.sun.jna.platform.win32.Variant.VT_VARIANT; +import com.sun.jna.platform.win32.WTypes.BSTR; +import com.sun.jna.platform.win32.WinDef.SCODE; +import java.lang.reflect.Array; + +public abstract class OaIdlUtil { + + /** + * Read SAFEARRAY into a java array. Not all VARTYPEs are supported! + * + *

    + * Supported types:

    + *
      + *
    • VT_BOOL
    • + *
    • VT_UI1
    • + *
    • VT_I1
    • + *
    • VT_UI2
    • + *
    • VT_I2
    • + *
    • VT_UI4
    • + *
    • VT_UINT
    • + *
    • VT_I4
    • + *
    • VT_INT
    • + *
    • VT_ERROR
    • + *
    • VT_R4
    • + *
    • VT_R8
    • + *
    • VT_DATE
    • + *
    • VT_BSTR
    • + *
    • VT_VARIANT (Onle the following VARTYPES): + *
        + *
      • VT_EMPTY (converted to NULL)
      • + *
      • VT_NULL
      • + *
      • VT_BOOL
      • + *
      • VT_UI1
      • + *
      • VT_I1
      • + *
      • VT_UI2
      • + *
      • VT_I2
      • + *
      • VT_UI4
      • + *
      • VT_UINT
      • + *
      • VT_I4
      • + *
      • VT_INT
      • + *
      • VT_ERROR
      • + *
      • VT_R4
      • + *
      • VT_R8
      • + *
      • VT_DATE
      • + *
      • VT_BSTR
      • + *
      + *
    • + *
    + * + * @param sa SAFEARRAY to convert + * @param destruct if true the supplied SAFEARRAY is destroyed, there must + * not be additional locks on the array! + * @return Java array corresponding to the given SAFEARRAY + */ + public static Object toPrimitiveArray(SAFEARRAY sa, boolean destruct) { + Pointer dataPointer = sa.accessData(); + try { + int dimensions = sa.getDimensionCount(); + int[] minIdx = new int[dimensions]; + int[] maxIdx = new int[dimensions]; + int[] elements = new int[dimensions]; + int[] cumElements = new int[dimensions]; + int varType = sa.getVarType().intValue(); + + for (int i = 0; i < dimensions; i++) { + minIdx[i] = sa.getLBound(i); + maxIdx[i] = sa.getUBound(i); + elements[i] = maxIdx[i] - minIdx[i] + 1; + } + + for (int i = dimensions - 1; i >= 0; i--) { + if (i == (dimensions - 1)) { + cumElements[i] = 1; + } else { + cumElements[i] = cumElements[i + 1] * elements[i + 1]; + } + } + + if (dimensions == 0) { + throw new IllegalArgumentException("Supplied Array has no dimensions."); + } + + int elementCount = cumElements[0] * elements[0]; + + Object sourceArray; + switch (varType) { + case VT_UI1: + case VT_I1: + sourceArray = dataPointer.getByteArray(0, elementCount); + break; + case VT_BOOL: + case VT_UI2: + case VT_I2: + sourceArray = dataPointer.getShortArray(0, elementCount); + break; + case VT_UI4: + case VT_UINT: + case VT_I4: + case VT_INT: + case VT_ERROR: + sourceArray = dataPointer.getIntArray(0, elementCount); + break; + case VT_R4: + sourceArray = dataPointer.getFloatArray(0, elementCount); + break; + case VT_R8: + case VT_DATE: + sourceArray = dataPointer.getDoubleArray(0, elementCount); + break; + case VT_BSTR: + sourceArray = dataPointer.getPointerArray(0, elementCount); + break; + case VT_VARIANT: + VARIANT variant = new VARIANT(dataPointer); + sourceArray = variant.toArray(elementCount); + break; + case VT_UNKNOWN: + case VT_DISPATCH: + case VT_CY: + case VT_DECIMAL: + case VT_RECORD: + default: + throw new IllegalStateException("Type not supported: " + varType); + } + + Object targetArray = Array.newInstance(Object.class, elements); + toPrimitiveArray(sourceArray, targetArray, minIdx, maxIdx, elements, cumElements, varType, new int[0]); + return targetArray; + } finally { + sa.unaccessData(); + if (destruct) { + sa.destroy(); + } + } + } + + private static void toPrimitiveArray(Object dataArray, Object targetArray, int[] minIdx, int[] maxIdx, int[] elements, int[] cumElements, int varType, int[] currentIdx) { + int dimIdx = currentIdx.length; + int[] subIdx = new int[currentIdx.length + 1]; + System.arraycopy(currentIdx, 0, subIdx, 0, dimIdx); + for (int i = minIdx[dimIdx]; i <= maxIdx[dimIdx]; i++) { + subIdx[dimIdx] = i; + if (dimIdx == (minIdx.length - 1)) { + int offset = 0; + for (int j = 0; j < dimIdx; j++) { + offset += cumElements[j] * currentIdx[j]; + } + offset += subIdx[dimIdx] - minIdx[dimIdx]; + int targetPos = subIdx[dimIdx] - minIdx[dimIdx]; + switch (varType) { + case VT_BOOL: + Array.set(targetArray, targetPos, Array.getShort(dataArray, offset) != 0); + break; + case VT_UI1: + case VT_I1: + Array.set(targetArray, targetPos, Array.getByte(dataArray, offset)); + break; + case VT_UI2: + case VT_I2: + Array.set(targetArray, targetPos, Array.getShort(dataArray, offset)); + break; + case VT_UI4: + case VT_UINT: + case VT_I4: + case VT_INT: + Array.set(targetArray, targetPos, Array.getInt(dataArray, offset)); + break; + case VT_ERROR: + Array.set(targetArray, targetPos, new SCODE(Array.getInt(dataArray, offset))); + break; + case VT_R4: + Array.set(targetArray, targetPos, Array.getFloat(dataArray, offset)); + break; + case VT_R8: + Array.set(targetArray, targetPos, Array.getDouble(dataArray, offset)); + break; + case VT_DATE: + Array.set(targetArray, targetPos, new DATE(Array.getDouble(dataArray, offset)).getAsJavaDate()); + break; + case VT_BSTR: + Array.set(targetArray, targetPos, new BSTR((Pointer) Array.get(dataArray, offset)).getValue()); + break; + case VT_VARIANT: + VARIANT holder = (VARIANT) Array.get(dataArray, offset); + switch (holder.getVarType().intValue()) { + case VT_NULL: + case VT_EMPTY: + Array.set(targetArray, targetPos, null); + break; + case VT_BOOL: + Array.set(targetArray, targetPos, holder.booleanValue()); + break; + case VT_UI1: + case VT_I1: + Array.set(targetArray, targetPos, holder.byteValue()); + break; + case VT_UI2: + case VT_I2: + Array.set(targetArray, targetPos, holder.shortValue()); + break; + case VT_UI4: + case VT_UINT: + case VT_I4: + case VT_INT: + Array.set(targetArray, targetPos, holder.intValue()); + break; + case VT_ERROR: + Array.set(targetArray, targetPos, new SCODE(holder.intValue())); + break; + case VT_R4: + Array.set(targetArray, targetPos, holder.floatValue()); + break; + case VT_R8: + Array.set(targetArray, targetPos, holder.doubleValue()); + break; + case VT_DATE: + Array.set(targetArray, targetPos, holder.dateValue()); + break; + case VT_BSTR: + Array.set(targetArray, targetPos, holder.stringValue()); + break; + default: + throw new IllegalStateException("Type not supported: " + holder.getVarType().intValue()); + } + break; + case VT_UNKNOWN: + case VT_DISPATCH: + case VT_CY: + case VT_DECIMAL: + case VT_RECORD: + default: + throw new IllegalStateException("Type not supported: " + varType); + } + } else { + toPrimitiveArray(dataArray, Array.get(targetArray, i), minIdx, maxIdx, elements, cumElements, varType, subIdx); + } + } + } +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/ObjBase.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/ObjBase.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/ObjBase.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/ObjBase.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,20 +1,27 @@ - - /* * Copyright 2010 Digital Rapids Corp. */ - - /* Copyright (c) 2010 Timothy Wall, All Rights Reserved - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Ole32.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Ole32.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Ole32.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Ole32.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2010 Daniel Doubrovkine, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; @@ -33,8 +44,7 @@ public interface Ole32 extends StdCallLibrary { /** The instance. */ - Ole32 INSTANCE = (Ole32) Native.loadLibrary("Ole32", Ole32.class, - W32APIOptions.UNICODE_OPTIONS); + Ole32 INSTANCE = Native.loadLibrary("Ole32", Ole32.class, W32APIOptions.DEFAULT_OPTIONS); /** * Creates a GUID, a unique 128-bit integer used for CLSIDs and interface @@ -217,6 +227,8 @@ * * REGDB_E_READREGDB The registry could not be opened for reading. */ + HRESULT CLSIDFromString(String lpsz, CLSID.ByReference pclsid); + /** @deprecated use the String version */ HRESULT CLSIDFromString(WString lpsz, CLSID.ByReference pclsid); /** diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Ole32Util.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Ole32Util.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Ole32Util.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Ole32Util.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2010 Daniel Doubrovkine, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/OleAuto.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/OleAuto.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/OleAuto.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/OleAuto.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,18 +1,29 @@ /* Copyright (c) 2012 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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 java.util.Arrays; +import com.sun.jna.Memory; import java.util.List; import com.sun.jna.Native; @@ -20,142 +31,156 @@ import com.sun.jna.Structure; import com.sun.jna.WString; import com.sun.jna.platform.win32.Guid.GUID; -import com.sun.jna.platform.win32.OaIdl.DISPIDByReference; +import com.sun.jna.platform.win32.OaIdl.DISPID; import com.sun.jna.platform.win32.OaIdl.SAFEARRAY; import com.sun.jna.platform.win32.OaIdl.SAFEARRAYBOUND; import com.sun.jna.platform.win32.Variant.VARIANT; import com.sun.jna.platform.win32.Variant.VariantArg; import com.sun.jna.platform.win32.WTypes.BSTR; import com.sun.jna.platform.win32.WTypes.VARTYPE; +import com.sun.jna.platform.win32.WTypes.VARTYPEByReference; import com.sun.jna.platform.win32.WinBase.SYSTEMTIME; import com.sun.jna.platform.win32.WinDef.LCID; +import com.sun.jna.platform.win32.WinDef.LONG; import com.sun.jna.platform.win32.WinDef.PVOID; import com.sun.jna.platform.win32.WinDef.UINT; import com.sun.jna.platform.win32.WinNT.HRESULT; -import com.sun.jna.platform.win32.COM.TypeLib; import com.sun.jna.ptr.DoubleByReference; import com.sun.jna.ptr.PointerByReference; import com.sun.jna.win32.StdCallLibrary; import com.sun.jna.win32.W32APIOptions; -// TODO: Auto-generated Javadoc /** * Oleaut32.dll Interface. - * + * * @author scott.palmer */ public interface OleAuto extends StdCallLibrary { + /** The instance. */ + OleAuto INSTANCE = Native.loadLibrary("OleAut32", OleAuto.class, W32APIOptions.DEFAULT_OPTIONS); /* Flags for IDispatch::Invoke */ /** The Constant DISPATCH_METHOD. */ - public final static int DISPATCH_METHOD = 0x1; + int DISPATCH_METHOD = 0x1; /** The Constant DISPATCH_PROPERTYGET. */ - public final static int DISPATCH_PROPERTYGET = 0x2; + int DISPATCH_PROPERTYGET = 0x2; /** The Constant DISPATCH_PROPERTYPUT. */ - public final static int DISPATCH_PROPERTYPUT = 0x4; + int DISPATCH_PROPERTYPUT = 0x4; /** The Constant DISPATCH_PROPERTYPUTREF. */ - public final static int DISPATCH_PROPERTYPUTREF = 0x8; + int DISPATCH_PROPERTYPUTREF = 0x8; /** An array that is allocated on the stac. */ - public final static int FADF_AUTO = 0x0001; + int FADF_AUTO = 0x0001; /** An array that is statically allocated. */ - public final static int FADF_STATIC = 0x0002; + int FADF_STATIC = 0x0002; /** An array that is embedded in a structure. */ - public final static int FADF_EMBEDDED = 0x0004; + int FADF_EMBEDDED = 0x0004; /** An array that is embedded in a structure. */ - public final static int FADF_FIXEDSIZE = 0x0010; + int FADF_FIXEDSIZE = 0x0010; /** An array that is embedded in a structure. */ - public final static int FADF_RECORD = 0x0020; + int FADF_RECORD = 0x0020; /** An array that is embedded in a structure. */ - public final static int FADF_HAVEIID = 0x0040; + int FADF_HAVEIID = 0x0040; /** * An array that has a variant type. The variant type can be retrieved with * SafeArrayGetVartype. */ - public final static int FADF_HAVEVARTYPE = 0x0080; + int FADF_HAVEVARTYPE = 0x0080; /** An array of BSTRs. */ - public final static int FADF_BSTR = 0x0100; + int FADF_BSTR = 0x0100; /** An array of IUnknown*. */ - public final static int FADF_UNKNOWN = 0x0200; + int FADF_UNKNOWN = 0x0200; /** An array of IDispatch*. */ - public final static int FADF_DISPATCH = 0x0400; + int FADF_DISPATCH = 0x0400; /** An array of VARIANTs. */ - public final static int FADF_VARIANT = 0x0800; + int FADF_VARIANT = 0x0800; /** Bits reserved for future use. */ - public final static int FADF_RESERVED = 0xF008; - - /** The instance. */ - OleAuto INSTANCE = (OleAuto) Native.loadLibrary("OleAut32", OleAuto.class, - W32APIOptions.UNICODE_OPTIONS); + int FADF_RESERVED = 0xF008; /** * This function allocates a new string and copies the passed string into * it. - * + * * @param sz * Null-terminated UNICODE string to copy. * @return Null if there is insufficient memory or if a null pointer is * passed in. */ - public BSTR SysAllocString(String sz); + BSTR SysAllocString(String sz); /** * This function frees a string allocated previously by SysAllocString, * SysAllocStringByteLen, SysReAllocString, SysAllocStringLen, or * SysReAllocStringLen. - * + * * @param bstr * Unicode string that was allocated previously, or NULL. Setting * this parameter to NULL causes the function to simply return. */ - public void SysFreeString(BSTR bstr); + void SysFreeString(BSTR bstr); /** + * Returns the length (in bytes) of a BSTR. + * + * @param bstr + * Unicode string that was allocated previously. + */ + int SysStringByteLen(BSTR bstr); + + /** + * Returns the length of a BSTR. + * + * @param bstr + * Unicode string that was allocated previously. + */ + int SysStringLen(BSTR bstr); + + /** * The VariantInit function initializes the VARIANTARG by setting the vt * field to VT_EMPTY. Unlike VariantClear, this function does not interpret * the current contents of the VARIANTARG. Use VariantInit to initialize new * local variables of type VARIANTARG (or VARIANT). - * + * * @param pvarg * The variant to initialize. */ - public void VariantInit(VARIANT.ByReference pvarg); + void VariantInit(VARIANT.ByReference pvarg); /** * The VariantInit function initializes the VARIANTARG by setting the vt * field to VT_EMPTY. Unlike VariantClear, this function does not interpret * the current contents of the VARIANTARG. Use VariantInit to initialize new * local variables of type VARIANTARG (or VARIANT). - * + * * @param pvarg * The variant to initialize. */ - public void VariantInit(VARIANT pvarg); + void VariantInit(VARIANT pvarg); /** * First, free any memory that is owned by pvargDest, such as VariantClear * (pvargDest must point to a valid initialized variant, and not simply to * an uninitialized memory location). Then pvargDest receives an exact copy * of the contents of pvargSrc. - * + * * If pvargSrc is a VT_BSTR, a copy of the string is made. If pvargSrcis a * VT_ARRAY, the entire array is copied. If pvargSrc is a VT_DISPATCH or * VT_UNKNOWN, AddRef is called to increment the object's reference count. - * + * * If the variant to be copied is a COM object that is passed by reference, * the vtfield of the pvargSrcparameter is VT_DISPATCH | VT_BYREF or * VT_UNKNOWN | VT_BYREF. In this case, VariantCopy does not increment the @@ -164,28 +189,28 @@ * to determine if it is necessary to increment the reference count of the * object. It is therefore the responsibility of the caller to call * IUnknown::AddRef on the object or not, as appropriate. - * + * * Note The VariantCopy method is not threadsafe. - * + * * @param pvargDest * [out] The destination variant. * @param pvargSrc * [in] The source variant. * @return the hresult */ - public HRESULT VariantCopy(Pointer pvargDest, VARIANT pvargSrc); + HRESULT VariantCopy(Pointer pvargDest, VARIANT pvargSrc); /** * Use this function to clear variables of type VARIANTARG (or VARIANT) * before the memory containing the VARIANTARG is freed (as when a local * variable goes out of scope). - * + * * The function clears a VARIANTARG by setting the vt field to VT_EMPTY. The * current contents of the VARIANTARG are released first. If the vtfield is * VT_BSTR, the string is freed. If the vtfield is VT_DISPATCH, the object * is released. If the vt field has the VT_ARRAY bit set, the array is * freed. - * + * * If the variant to be cleared is a COM object that is passed by reference, * the vtfield of the pvargparameter is VT_DISPATCH | VT_BYREF or VT_UNKNOWN * | VT_BYREF. In this case, VariantClear does not release the object. @@ -193,7 +218,7 @@ * object, VariantClear has no way to determine if it is necessary to * release the object. It is therefore the responsibility of the caller to * release the object or not, as appropriate. - * + * * In certain cases, it may be preferable to clear a variant in code without * calling VariantClear. For example, you can change the type of a VT_I4 * variant to another type without calling this function. Safearrays of BSTR @@ -202,46 +227,46 @@ * handled. Safearrays of variant will also have VariantClear called on each * member. Using VariantClear in these cases ensures that code will continue * to work if Automation adds new variant types in the future. - * + * * Do not use VariantClear on unitialized variants; use VariantInit to * initialize a new VARIANTARG or VARIANT. - * + * * Variants containing arrays with outstanding references cannot be cleared. * Attempts to do so will return an HRESULT containing DISP_E_ARRAYISLOCKED. - * + * * @param pvarg * [in, out] The variant to clear. * @return the hresult */ - HRESULT VariantClear(Pointer pvarg); + HRESULT VariantClear(VARIANT pvarg); /** * Creates a new array descriptor, allocates and initializes the data for * the array, and returns a pointer to the new array descriptor. - * + * * @param vt * [in] The base type of the array (the VARTYPE of each element * of the array). The VARTYPE is restricted to a subset of the * variant types. Neither the VT_ARRAY nor the VT_BYREF flag can * be set. VT_EMPTY and VT_NULL are not valid base types for the * array. All other types are legal. cDims - * + * * @param cDims - * the c dims + * the number of dims * @param rgsabound * the rgsabound - * + * * @return Return value - * + * * A safe array descriptor, or null if the array could not be * created. */ - public SAFEARRAY.ByReference SafeArrayCreate(VARTYPE vt, int cDims, + SAFEARRAY.ByReference SafeArrayCreate(VARTYPE vt, UINT cDims, SAFEARRAYBOUND[] rgsabound); /** * Stores the data element at the specified location in the array. - * + * * @param psa * [in] An array descriptor created by SafeArrayCreate. * @param idx @@ -251,22 +276,68 @@ * VT_DISPATCH, VT_UNKNOWN, and VT_BSTR are pointers, and do not * require another level of indirection. * @return Return value - * + * * This function can return one of these values. - * - * S_OK Success. - * - * DISP_E_BADINDEX The specified index is not valid. - * - * E_INVALIDARG One of the arguments is not valid. - * - * E_OUTOFMEMORY Memory could not be allocated for the element. + * + *
    + *
    S_OK
    Success.
    + *
    DISP_E_BADINDEX
    The specified index is not valid.
    + *
    E_INVALIDARG
    One of the arguments is not valid.
    + *
    E_OUTOFMEMORY
    Memory could not be allocated for the element.
    + *
    */ - public HRESULT SafeArrayPutElement(SAFEARRAY psa, long[] idx, VARIANT pv); + HRESULT SafeArrayPutElement(SAFEARRAY psa, LONG[] idx, Pointer pv); /** + * Retrieve the upper bound for the specified dimension of the supplied array + * + * @param psa + * [in] An array descriptor created by SafeArrayCreate. + * @param nDim + * [in] the dimension, one based + * @param bound + * [out] upper bound for the supplied dimension + * + * @return Return value + * + * This function can return one of these values. + * + *
    + *
    S_OK
    Success.
    + *
    DISP_E_BADINDEX
    The specified index is not valid.
    + *
    E_INVALIDARG
    One of the arguments is not valid.
    + *
    + */ + HRESULT SafeArrayGetUBound(SAFEARRAY psa, UINT nDim, WinDef.LONGByReference bound); + + /** + * Retrieve the lower bound for the specified dimension of the supplied array + * + * @param psa + * [in] An array descriptor created by SafeArrayCreate. + * @param nDim + * [in] the dimension, one based + * @param bound + * [out] lower bound for the supplied dimension + * + * @return Return value + * + * This function can return one of these values. + * + *
    + *
    S_OK
    Success.
    + *
    DISP_E_BADINDEX
    The specified index is not valid.
    + *
    E_INVALIDARG
    One of the arguments is not valid.
    + *
    + */ + HRESULT SafeArrayGetLBound(SAFEARRAY psa, UINT nDim, WinDef.LONGByReference bound); + + + /** * Retrieves a single element of the array. - * + * + * The array is automaticly locked via SafeArrayLock and SafeArrayUnlock. + * * @param psa * [in] An array descriptor created by SafeArrayCreate. * @param rgIndices @@ -275,63 +346,204 @@ * left-most dimension is stored at rgIndices[psa->cDims - 1]. * @param pv * [out] The element of the array. - * + * * @return Return value - * + * * This function can return one of these values. - * - * S_OK Success. - * - * DISP_E_BADINDEX The specified index is not valid. - * - * E_INVALIDARG One of the arguments is not valid. - * - * E_OUTOFMEMORY Memory could not be allocated for the element. - */ - public HRESULT SafeArrayGetElement(SAFEARRAY psa, long[] rgIndices, - Pointer pv); + * + *
    + *
    S_OK
    Success.
    + *
    DISP_E_BADINDEX
    The specified index is not valid.
    + *
    E_INVALIDARG
    One of the arguments is not valid.
    + *
    E_OUTOFMEMORY
    Memory could not be allocated for the element.
    + *
    + */ + HRESULT SafeArrayGetElement(SAFEARRAY psa, LONG[] rgIndices, Pointer pv); /** + * Retrieves the pointer to a single element of the array. + * + *

    The caller is responsible for locking.

    + * + * @param psa + * [in] An array descriptor created by SafeArrayCreate. + * @param rgIndices + * [in] A vector of indexes for each dimension of the array. The + * right-most (least significant) dimension is rgIndices[0]. The + * left-most dimension is stored at rgIndices[psa->cDims - 1]. + * @param ppv + * [out] The element of the array. + * + * @return Return value + * + * This function can return one of these values. + * + *
    + *
    S_OK
    Success.
    + *
    DISP_E_BADINDEX
    The specified index is not valid.
    + *
    E_INVALIDARG
    One of the arguments is not valid.
    + *
    + */ + HRESULT SafeArrayPtrOfIndex(SAFEARRAY psa, LONG[] rgIndices, PointerByReference ppv); + + /** * Increments the lock count of an array, and places a pointer to the array * data in pvData of the array descriptor. - * + * * @param psa * [in] An array descriptor created by SafeArrayCreate. - * + * * @return Return value - * + * * This function can return one of these values. - * - * S_OK Success. - * - * E_INVALIDARG The argument psa is not valid. - * - * E_UNEXPECTED The array could not be locked. + * + *
    + *
    S_OK
    Success.
    + *
    E_INVALIDARG
    The argument psa is not valid.
    + *
    E_UNEXPECTED
    The array could not be locked.
    + *
    */ - public HRESULT SafeArrayLock(SAFEARRAY psa); + HRESULT SafeArrayLock(SAFEARRAY psa); /** * Decrements the lock count of an array so it can be freed or resized. - * + * * @param psa * [in] An array descriptor created by SafeArrayCreate. - * + * * @return Return value - * + * * This function can return one of these values. - * - * S_OK Success. - * - * E_INVALIDARG The argument psa is not valid. - * - * E_UNEXPECTED The array could not be locked. - */ - public HRESULT SafeArrayUnLock(SAFEARRAY psa); + * + *
    + *
    S_OK
    Success.
    + *
    E_INVALIDARG
    The argument psa is not valid.
    + *
    E_UNEXPECTED
    The array could not be locked.
    + *
    + */ + HRESULT SafeArrayUnlock(SAFEARRAY psa); /** + * Destroys an existing array descriptor and all of the data in the array. + * If objects are stored in the array, Release is called on each object + * in the array. + * + * @param psa + * [in] An array descriptor created by SafeArrayCreate. + * + * @return Return value + * + * This function can return one of these values. + * + *
    + *
    S_OK
    Success.
    + *
    E_INVALIDARG
    The argument psa is not valid.
    + *
    DISP_E_ARRAYISLOCKED
    The array could not be locked.
    + *
    + */ + HRESULT SafeArrayDestroy(SAFEARRAY psa); + + /** + * Changes the right-most (least significant) bound of the specified safe array. + * + * @param psa + * [in, out] An array descriptor created by SafeArrayCreate. + * @param psaboundNew + * [in] New bounds for the least significant dimension + * + * @return Return value + * + * This function can return one of these values. + * + *
    + *
    S_OK
    Success.
    + *
    E_INVALIDARG
    The argument psa is not valid.
    + *
    DISP_E_ARRAYISLOCKED
    The array could not be locked.
    + *
    + */ + HRESULT SafeArrayRedim(SAFEARRAY psa, SAFEARRAYBOUND psaboundNew); + + /** + * Return VARTYPE of the SAFEARRAY + * + * @param psa + * [in] An array descriptor created by SafeArrayCreate. + * @param pvt + * [in] Vartype of the SAFEARRAY + * + * @return Return value + * + * This function can return one of these values. + * + *
    + *
    S_OK
    Success.
    + *
    E_INVALIDARG
    The argument psa is not valid.
    + *
    + */ + HRESULT SafeArrayGetVartype(SAFEARRAY psa, VARTYPEByReference pvt); + + /** + * Return number of dimensions of the SAFEARRAY + * + * @param psa + * [in] An array descriptor created by SafeArrayCreate. + * + * @return Return count of dimensions + */ + UINT SafeArrayGetDim(SAFEARRAY psa); + + /** + * Lock array and retrieve pointer to data + * + * @param psa + * [in] An array descriptor created by SafeArrayCreate. + * @param ppvData + * [in] pointer to the data array + * + * @return Return value + * + * This function can return one of these values. + * + *
    + *
    S_OK
    Success.
    + *
    E_INVALIDARG
    The argument psa is not valid.
    + *
    E_UNEXPECTED
    The array could not be locked.
    + *
    + */ + HRESULT SafeArrayAccessData(SAFEARRAY psa, PointerByReference ppvData); + + /** + * Unlock array and invalidate the pointer retrieved via SafeArrayAccessData + * + * @param psa + * [in] An array descriptor created by SafeArrayCreate. + * + * @return Return value + * + * This function can return one of these values. + * + *
    + *
    S_OK
    Success.
    + *
    E_INVALIDARG
    The argument psa is not valid.
    + *
    E_UNEXPECTED
    The array could not be locked.
    + *
    + */ + HRESULT SafeArrayUnaccessData(SAFEARRAY psa); + + /** + * Get size of one element in bytes + * + * @param psa + * [in] An array descriptor created by SafeArrayCreate. + * + * @return size in bytes + */ + UINT SafeArrayGetElemsize(SAFEARRAY psa); + + /** * Retrieves a pointer to a running object that has been registered with * OLE. - * + * * @param rclsid * [in] The class identifier (CLSID) of the active object from * the OLE registration database. @@ -339,14 +551,13 @@ * Reserved for future use. Must be null. * @param ppunk * [out] The requested active object. - * + * * @return Return value - * + * * If this function succeeds, it returns S_OK. Otherwise, it returns * an HRESULT error code. */ - HRESULT GetActiveObject(GUID rclsid, PVOID pvReserved, - PointerByReference ppunk); + HRESULT GetActiveObject(GUID rclsid, PVOID pvReserved, PointerByReference ppunk); /** * The Class DISPPARAMS. @@ -359,19 +570,66 @@ public static class ByReference extends DISPPARAMS implements Structure.ByReference { } + public static final List FIELDS = createFieldsOrder("rgvarg", "rgdispidNamedArgs", "cArgs", "cNamedArgs"); /** The rgvarg. */ public VariantArg.ByReference rgvarg; - /** The rgdispid named args. */ - public DISPIDByReference rgdispidNamedArgs; + /** The rgdispid named args. */ + public Pointer rgdispidNamedArgs = Pointer.NULL; - /** The c args. */ - public UINT cArgs; + /** The c args. - use setArgs to update arguments */ + public UINT cArgs = new UINT(0); - /** The c named args. */ - public UINT cNamedArgs; + /** The c named args. - use setRgdispidNamedArgs to update named arguments map */ + public UINT cNamedArgs = new UINT(0); + public DISPID[] getRgdispidNamedArgs() { + DISPID[] namedArgs = null; + int count = cNamedArgs.intValue(); + if(rgdispidNamedArgs != null && count > 0) { + int[] rawData = rgdispidNamedArgs.getIntArray(0, count); + namedArgs = new DISPID[count]; + for(int i = 0; i < count; i++) { + namedArgs[i] = new DISPID(rawData[i]); + } + } else { + namedArgs = new DISPID[0]; + } + return namedArgs; + } + + public void setRgdispidNamedArgs(DISPID[] namedArgs) { + if(namedArgs == null) { + namedArgs = new DISPID[0]; + } + cNamedArgs = new UINT(namedArgs.length); + rgdispidNamedArgs = new Memory(DISPID.SIZE * namedArgs.length); + int[] rawData = new int[namedArgs.length]; + for(int i = 0; i < rawData.length; i++) { + rawData[i] = namedArgs[i].intValue(); + } + rgdispidNamedArgs.write(0, rawData, 0, namedArgs.length); + } + + public VARIANT[] getArgs() { + if(this.rgvarg != null) { + this.rgvarg.setArraySize(cArgs.intValue()); + return this.rgvarg.variantArg; + } else { + return new VARIANT[0]; + } + } + + public void setArgs(VARIANT[] arguments) { + if(arguments == null) { + arguments = new VARIANT[0]; + } + + rgvarg = new VariantArg.ByReference(arguments); + cArgs = new UINT(arguments.length); + } + /** * Instantiates a new dispparams. */ @@ -381,7 +639,7 @@ /** * Instantiates a new dispparams. - * + * * @param memory * the memory */ @@ -390,21 +648,15 @@ this.read(); } - /* - * (non-Javadoc) - * - * @see com.sun.jna.Structure#getFieldOrder() - */ @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "rgvarg", "rgdispidNamedArgs", - "cArgs", "cNamedArgs" }); + protected List getFieldOrder() { + return FIELDS; } } /** * Uses registry information to load a type library. - * + * * @param rguid * The GUID of the library. * @param wVerMajor @@ -415,77 +667,78 @@ * The national language code of the library. * @param pptlib * The loaded type library. - * + * * This function can return one of these values: S_OK Success. - * + * * E_INVALIDARG One or more of the arguments is not valid. - * + * * E_OUTOFMEMORY Insufficient memory to complete the operation. - * + * * TYPE_E_IOERROR The function could not write to the file. - * + * * TYPE_E_INVALIDSTATE The type library could not be opened. - * + * * TYPE_E_INVDATAREAD The function could not read from the file. - * + * * TYPE_E_UNSUPFORMAT The type library has an older format. - * + * * TYPE_E_UNKNOWNLCID The LCID could not be found in the * OLE-supported DLLs. - * + * * TYPE_E_CANTLOADLIBRARY The type library or DLL could not be * loaded. - * @return status + * @return status */ - public HRESULT LoadRegTypeLib(GUID rguid, int wVerMajor, int wVerMinor, - LCID lcid, PointerByReference pptlib); + HRESULT LoadRegTypeLib(GUID rguid, int wVerMajor, int wVerMinor, LCID lcid, PointerByReference pptlib); /** * Loads and registers a type library. - * + * * @param szFile * The name of the file from which the method should attempt to * load a type library. - * + * * @param pptlib * The loaded type library. Return value - * + * * This function can return one of these values. - * + * * S_OK Success. - * + * * E_INVALIDARG One or more of the arguments is not valid. - * + * * E_OUTOFMEMORY Insufficient memory to complete the operation. - * + * * TYPE_E_IOERROR The function could not write to the file. - * + * * TYPE_E_INVALIDSTATE The type library could not be opened. - * + * * TYPE_E_INVDATAREAD The function could not read from the file. - * + * * TYPE_E_UNSUPFORMAT The type library has an older format. - * + * * TYPE_E_UNKNOWNLCID The LCID could not be found in the * OLE-supported DLLs. - * + * * TYPE_E_CANTLOADLIBRARY The type library or DLL could not be * loaded. * @return status */ - public HRESULT LoadTypeLib(WString szFile, PointerByReference pptlib); + HRESULT LoadTypeLib(String szFile, PointerByReference pptlib); + /** @deprecated use the String version */ + @Deprecated + HRESULT LoadTypeLib(WString szFile, PointerByReference pptlib); /** * Converts a system time to a variant representation. - * + * * @param lpSystemTime * [in] The system time. - * + * * @param pvtime * [out] The variant time. - * + * * @return The function returns TRUE on success and FALSE otherwise. */ - public int SystemTimeToVariantTime(SYSTEMTIME lpSystemTime, - DoubleByReference pvtime); + int SystemTimeToVariantTime(SYSTEMTIME lpSystemTime, DoubleByReference pvtime); } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/OleAutoUtil.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/OleAutoUtil.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/OleAutoUtil.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/OleAutoUtil.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,78 +0,0 @@ -/* Copyright (c) 2012 Tobias Wolf, All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32; - -import com.sun.jna.platform.win32.OaIdl.SAFEARRAY; -import com.sun.jna.platform.win32.OaIdl.SAFEARRAYBOUND; -import com.sun.jna.platform.win32.Variant.VARIANT; -import com.sun.jna.platform.win32.WTypes.VARTYPE; -import com.sun.jna.platform.win32.WinNT.HRESULT; -import com.sun.jna.platform.win32.COM.COMUtils; - -// TODO: Auto-generated Javadoc -/** - * The Class OleAut32Util. - * - * @author Tobias Wolf, wolf.tobias@gmx.net - */ -public abstract class OleAutoUtil { - - /** - * Creates a new the variant array. - * - * @param size the size - * @return the sAFEARRA y. by reference - */ - public static SAFEARRAY.ByReference createVarArray(int size) { - SAFEARRAY.ByReference psa; - SAFEARRAYBOUND[] rgsabound = new SAFEARRAYBOUND[1]; - rgsabound[0] = new SAFEARRAYBOUND(size, 0); - - psa = OleAuto.INSTANCE.SafeArrayCreate( - new VARTYPE(Variant.VT_VARIANT), 1, rgsabound); - - return psa; - } - - /** - * Safe array put element. - * - * @param array the array - * @param index the index - * @param arg the arg - */ - public static void SafeArrayPutElement(SAFEARRAY array, long index, - VARIANT arg) { - long[] idx = new long[1]; - idx[0] = index; - HRESULT hr = OleAuto.INSTANCE.SafeArrayPutElement(array, idx, arg); - COMUtils.SUCCEEDED(hr); - } - - /** - * Safe array get element. - * - * @param array the array - * @param index the index - * @return the variant - */ - public static VARIANT SafeArrayGetElement(SAFEARRAY array, long index) { - long[] idx = new long[1]; - idx[0] = index; - VARIANT result = new VARIANT(); - HRESULT hr = OleAuto.INSTANCE.SafeArrayGetElement(array, idx, - result.getPointer()); - COMUtils.SUCCEEDED(hr); - return result; - } -} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/OpenGL32.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/OpenGL32.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/OpenGL32.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/OpenGL32.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,28 +1,38 @@ /* Copyright (c) 2011 Timothy Wall, 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.Native; import com.sun.jna.Pointer; import com.sun.jna.platform.win32.WinDef.HDC; -import com.sun.jna.platform.win32.WinDef.HGLRC; import com.sun.jna.win32.StdCallLibrary; /** * opengl32.dll Interface. */ public interface OpenGL32 extends StdCallLibrary { - OpenGL32 INSTANCE = (OpenGL32) Native.loadLibrary("opengl32", OpenGL32.class); + OpenGL32 INSTANCE = Native.loadLibrary("opengl32", OpenGL32.class); /** * The glGetString function returns a string describing the current OpenGL connection. @@ -31,7 +41,7 @@ * One of the following symbolic constants. * @return The glGetString function returns a pointer to a static string describing some aspect of the current OpenGL connection. */ - public String glGetString(int name); + String glGetString(int name); /** * The wglCreateContext function creates a new OpenGL rendering context, which is suitable for drawing on the device @@ -41,7 +51,7 @@ * Handle to a device context for which the function creates a suitable OpenGL rendering context. * @return handle to an OpenGL rendering context */ - public WinDef.HGLRC wglCreateContext(HDC windowDC); + WinDef.HGLRC wglCreateContext(HDC windowDC); /** * The wglGetCurrentContext function obtains a handle to the current OpenGL rendering context of the calling thread. @@ -49,7 +59,7 @@ * @return If the calling thread has a current OpenGL rendering context, wglGetCurrentContext returns a * handle to that rendering context. Otherwise, the return value is NULL. */ - public WinDef.HGLRC wglGetCurrentContext(); + WinDef.HGLRC wglGetCurrentContext(); /** * The wglMakeCurrent function makes a specified OpenGL rendering context the calling thread's current rendering @@ -62,7 +72,7 @@ * Handle to an OpenGL rendering context that the function sets as the calling thread's rendering context. * @return true if successful */ - public boolean wglMakeCurrent(HDC windowDC, WinDef.HGLRC hglrc); + boolean wglMakeCurrent(HDC windowDC, WinDef.HGLRC hglrc); /** * The wglDeleteContext function deletes a specified OpenGL rendering context. @@ -71,7 +81,7 @@ * Handle to an OpenGL rendering context that the function will delete. * @return true if successful */ - public boolean wglDeleteContext(WinDef.HGLRC hglrc); + boolean wglDeleteContext(WinDef.HGLRC hglrc); /** * The wglGetProcAddress function returns the address of an OpenGL extension function for use with the @@ -82,5 +92,5 @@ * The name of the extension function must be identical to a corresponding function implemented by OpenGL. * @return When the function succeeds, the return value is the address of the extension function. */ - public Pointer wglGetProcAddress(String lpszProc); + Pointer wglGetProcAddress(String lpszProc); } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/OpenGL32Util.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/OpenGL32Util.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/OpenGL32Util.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/OpenGL32Util.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2011 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Pdh.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Pdh.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Pdh.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Pdh.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,18 +1,28 @@ /* Copyright (c) 2015 Goldstein Lyor, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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 java.util.Arrays; import java.util.List; import com.sun.jna.Native; @@ -32,24 +42,22 @@ * @see Performance Counters */ public interface Pdh extends StdCallLibrary { - Pdh INSTANCE = (Pdh) Native.loadLibrary("Pdh", - Pdh.class, W32APIOptions.UNICODE_OPTIONS); - + Pdh INSTANCE = Native.loadLibrary("Pdh", Pdh.class, W32APIOptions.DEFAULT_OPTIONS); /** Maximum counter name length. */ - public static final int PDH_MAX_COUNTER_NAME = 1024; + int PDH_MAX_COUNTER_NAME = 1024; /** Maximum counter instance name length. */ - public static final int PDH_MAX_INSTANCE_NAME = 1024; + int PDH_MAX_INSTANCE_NAME = 1024; /** Maximum full counter path length. */ - public static final int PDH_MAX_COUNTER_PATH = 2048; + int PDH_MAX_COUNTER_PATH = 2048; /** Maximum full counter log name length. */ - public static final int PDH_MAX_DATASOURCE_PATH = 1024; + int PDH_MAX_DATASOURCE_PATH = 1024; /* TODO * LPVOID CALLBACK AllocateMemory(_In_ SIZE_T AllocSize,_In_ LPVOID pContext) * void CALLBACK FreeMemory(LPVOID pBuffer,LPVOID pContext) */ - + /** * Connects to the specified computer. * @param szMachineName The name of the computer to connect to. If @@ -60,13 +68,13 @@ int PdhConnectMachine(String szMachineName); // Known values for the PdhGetDllVersion result - public static final int PDH_CVERSION_WIN40 = 0x0400; - public static final int PDH_CVERSION_WIN50 = 0x0500; + int PDH_CVERSION_WIN40 = 0x0400; + int PDH_CVERSION_WIN50 = 0x0500; // v1.1 revision of PDH -- basic log functions // v1.2 of the PDH -- adds variable instance counters // v1.3 of the PDH -- adds log service control & stubs for NT5/PDH v2 fn's // v2.0 of the PDH -- is the NT v 5.0 B2 version - public static final int PDH_VERSION = PDH_CVERSION_WIN50 + 0x0003; + int PDH_VERSION = PDH_CVERSION_WIN50 + 0x0003; /** * Returns the version of the currently installed Pdh.dll file. @@ -86,7 +94,7 @@ * @see PdhOpenQuery */ int PdhOpenQuery(String szDataSource, DWORD_PTR dwUserData, HANDLEByReference phQuery); - + /** * Closes all counters contained in the specified query, closes all * handles related to the query, and frees all memory associated with @@ -103,6 +111,10 @@ * @see Windows Server 2003 Performance Counters Reference */ public class PDH_COUNTER_PATH_ELEMENTS extends Structure { + public static final List FIELDS = createFieldsOrder( + "szMachineName", "szObjectName", "szInstanceName", + "szParentInstance", "dwInstanceIndex", "szCounterName"); + public String szMachineName; public String szObjectName; public String szInstanceName; @@ -112,14 +124,13 @@ @Override protected List getFieldOrder() { - return Arrays.asList("szMachineName", "szObjectName", "szInstanceName", - "szParentInstance", "dwInstanceIndex", "szCounterName"); + return FIELDS; } } // flags for the PdhMakeCounterPath - public static final int PDH_PATH_WBEM_RESULT = 0x00000001; - public static final int PDH_PATH_WBEM_INPUT = 0x00000002; + int PDH_PATH_WBEM_RESULT = 0x00000001; + int PDH_PATH_WBEM_INPUT = 0x00000002; /** * Creates a full counter path using the members specified in the @@ -133,7 +144,7 @@ * zero on input, the function returns PDH_MORE_DATA and sets this parameter * to the required buffer size. If the buffer is larger than the required * size, the function sets this parameter to the actual size of the buffer - * that was used. + * that was used. * @param dwFlags Format of the input and output counter values. * @return ERROR_SUCCESS (or PDH_MORE_DATA) * @see PdhMakeCounterPath @@ -168,6 +179,8 @@ * @see PDH_RAW_COUNTER */ public class PDH_RAW_COUNTER extends Structure { + public static final List FIELDS = createFieldsOrder("CStatus", "TimeStamp", "FirstValue", "SecondValue", "MultiCount"); + /** Counter status that indicates if the counter value is valid. */ public int CStatus; /** Local time for when the data was collected */ @@ -185,7 +198,7 @@ @Override protected List getFieldOrder() { - return Arrays.asList("CStatus", "TimeStamp", "FirstValue", "SecondValue", "MultiCount"); + return FIELDS; } } @@ -199,18 +212,18 @@ int PdhGetRawCounterValue(HANDLE hCounter, DWORDByReference lpdwType, PDH_RAW_COUNTER pValue); // counter value types - public static final int PDH_FMT_RAW = 0x00000010; - public static final int PDH_FMT_ANSI = 0x00000020; - public static final int PDH_FMT_UNICODE = 0x00000040; - public static final int PDH_FMT_LONG = 0x00000100; - public static final int PDH_FMT_DOUBLE = 0x00000200; - public static final int PDH_FMT_LARGE = 0x00000400; - public static final int PDH_FMT_NOSCALE = 0x00001000; - public static final int PDH_FMT_1000 = 0x00002000; - public static final int PDH_FMT_NODATA = 0x00004000; - public static final int PDH_FMT_NOCAP100 = 0x00008000; - public static final int PERF_DETAIL_COSTLY = 0x00010000; - public static final int PERF_DETAIL_STANDARD = 0x0000FFFF; + int PDH_FMT_RAW = 0x00000010; + int PDH_FMT_ANSI = 0x00000020; + int PDH_FMT_UNICODE = 0x00000040; + int PDH_FMT_LONG = 0x00000100; + int PDH_FMT_DOUBLE = 0x00000200; + int PDH_FMT_LARGE = 0x00000400; + int PDH_FMT_NOSCALE = 0x00001000; + int PDH_FMT_1000 = 0x00002000; + int PDH_FMT_NODATA = 0x00004000; + int PDH_FMT_NOCAP100 = 0x00008000; + int PERF_DETAIL_COSTLY = 0x00010000; + int PERF_DETAIL_STANDARD = 0x0000FFFF; /** * Validates that the counter is present on the computer specified in the counter path. @@ -228,7 +241,7 @@ * @see PdhCollectQueryData */ int PdhCollectQueryData(HANDLE hQuery); - + /** * Uses a separate thread to collect the current raw data value for all counters * in the specified query. The function then signals the application-defined @@ -243,7 +256,7 @@ * @see PdhCollectQueryDataEx */ int PdhCollectQueryDataEx(HANDLE hQuery, int dwIntervalTime, HANDLE hNewDataEvent); - + /** * Collects the current raw data value for all counters in the specified * query and updates the status code of each counter. @@ -254,27 +267,29 @@ * @see PdhCollectQueryDataWithTime */ int PdhCollectQueryDataWithTime(HANDLE hQuery, LONGLONGByReference pllTimeStamp); - + /** * Information on time intervals as applied to the sampling of performance data. * @see PDH_TIME_INFO */ public class PDH_TIME_INFO extends Structure { + public static final List FIELDS = createFieldsOrder("StartTime", "EndTime", "SampleCount"); /** Starting time of the sample interval, in local FILETIME format. */ public long StartTime; /** Ending time of the sample interval, in local FILETIME format. */ public long EndTime; /** Number of samples collected during the interval. */ public int SampleCount; - + + @Override protected List getFieldOrder() { - return Arrays.asList("StartTime", "EndTime", "SampleCount"); + return FIELDS; } } - + /** - * @param hQuery Handle to the query. - * @param pInfo A {@link PDH_TIME_INFO} structure that specifies the time range. + * @param hQuery Handle to the query. + * @param pInfo A {@link PDH_TIME_INFO} structure that specifies the time range. * @return ERROR_SUCCESS if successful * @see PdhSetQueryTimeRange */ diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/PdhMsg.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/PdhMsg.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/PdhMsg.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/PdhMsg.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2015 Goldstein Lyor, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/PhysicalMonitorEnumerationAPI.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/PhysicalMonitorEnumerationAPI.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/PhysicalMonitorEnumerationAPI.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/PhysicalMonitorEnumerationAPI.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,22 +1,30 @@ /* * Copyright 2014 Martin Steiger * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * 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 java.util.Arrays; import java.util.List; import com.sun.jna.Structure; @@ -40,14 +48,14 @@ final int PHYSICAL_MONITOR_DESCRIPTION_SIZE = 128; /****************************************************************************** - Physical Monitor Structures + Physical Monitor Structures ******************************************************************************/ /** * Contains a handle and text description corresponding to a physical monitor. */ - public class PHYSICAL_MONITOR extends Structure - { + public class PHYSICAL_MONITOR extends Structure { + public static final List FIELDS = createFieldsOrder("hPhysicalMonitor", "szPhysicalMonitorDescription"); /** * Handle to the physical monitor. */ @@ -59,9 +67,8 @@ public char[] szPhysicalMonitorDescription = new char[PHYSICAL_MONITOR_DESCRIPTION_SIZE]; @Override - protected List getFieldOrder() - { - return Arrays.asList("hPhysicalMonitor", "szPhysicalMonitorDescription"); + protected List getFieldOrder() { + return FIELDS; } } } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Psapi.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Psapi.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Psapi.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Psapi.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,106 +1,306 @@ -/* Copyright (c) 2015 Andreas "PAX" L\u00FCck, All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32; - -import com.sun.jna.Native; -import com.sun.jna.Pointer; -import com.sun.jna.platform.win32.WinNT.HANDLE; -import com.sun.jna.win32.StdCallLibrary; -import com.sun.jna.win32.W32APIOptions; - -/** - * The process status application programming interface (PSAPI) is a helper - * library that makes it easier for you to obtain information about processes - * and device drivers. - * - * @author Andreas "PAX" Lück, onkelpax-git[at]yahoo.de - */ -public interface Psapi extends StdCallLibrary { - public static final Psapi INSTANCE = (Psapi) Native.loadLibrary("psapi", - Psapi.class, W32APIOptions.DEFAULT_OPTIONS); - - /** - * Retrieves the fully qualified path for the file containing the specified - * module. - * - * @param process - * A handle to the process that contains the module. - * @param module - * A handle to the module. If this parameter is NULL, - * GetModuleFileNameEx returns the path of the executable file of - * the process specified in hProcess. - * @param lpFilename - * A pointer to a buffer that receives the fully qualified path - * to the module. If the size of the file name is larger than the - * value of the nSize parameter, the function succeeds but the - * file name is truncated and null-terminated. - * @param nSize - * The size of the lpFilename buffer, in characters. - * @return If the function succeeds, the return value specifies the length - * of the string copied to the buffer. If the function fails, the - * return value is zero. To get extended error information, call - * {@link Kernel32Util#getLastErrorMessage()}. - */ - int GetModuleFileNameExA(final HANDLE process, final HANDLE module, - final byte[] lpFilename, final int nSize); - - /** - * Retrieves the fully qualified path for the file containing the specified - * module. - * - * @param process - * A handle to the process that contains the module. - * @param module - * A handle to the module. If this parameter is NULL, - * GetModuleFileNameEx returns the path of the executable file of - * the process specified in hProcess. - * @param lpFilename - * A pointer to a buffer that receives the fully qualified path - * to the module. If the size of the file name is larger than the - * value of the nSize parameter, the function succeeds but the - * file name is truncated and null-terminated. - * @param nSize - * The size of the lpFilename buffer, in characters. - * @return If the function succeeds, the return value specifies the length - * of the string copied to the buffer. If the function fails, the - * return value is zero. To get extended error information, call - * {@link Kernel32Util#getLastErrorMessage()}. - */ - int GetModuleFileNameExW(final HANDLE process, final HANDLE module, - final char[] lpFilename, final int nSize); - - /** - * Retrieves the fully qualified path for the file containing the specified - * module. - * - * @param process - * A handle to the process that contains the module. - * @param module - * A handle to the module. If this parameter is NULL, - * GetModuleFileNameEx returns the path of the executable file of - * the process specified in hProcess. - * @param lpFilename - * A pointer to a buffer that receives the fully qualified path - * to the module. If the size of the file name is larger than the - * value of the nSize parameter, the function succeeds but the - * file name is truncated and null-terminated. - * @param nSize - * The size of the lpFilename buffer, in characters. - * @return If the function succeeds, the return value specifies the length - * of the string copied to the buffer. If the function fails, the - * return value is zero. To get extended error information, call - * {@link Kernel32Util#getLastErrorMessage()}. - */ - int GetModuleFileNameEx(final HANDLE process, final HANDLE module, - final Pointer lpFilename, final int nSize); -} +/* Copyright (c) 2015 Andreas "PAX" L\u00FCck, 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 java.util.List; + +import com.sun.jna.Native; +import com.sun.jna.Pointer; +import com.sun.jna.Structure; +import com.sun.jna.platform.win32.BaseTSD.SIZE_T; +import com.sun.jna.platform.win32.WinDef.DWORD; +import com.sun.jna.platform.win32.WinDef.HMODULE; +import com.sun.jna.platform.win32.WinNT.HANDLE; +import com.sun.jna.ptr.IntByReference; +import com.sun.jna.win32.StdCallLibrary; +import com.sun.jna.win32.W32APIOptions; + +/** + * The process status application programming interface (PSAPI) is a helper + * library that makes it easier for you to obtain information about processes + * and device drivers. + * + * @author Andreas "PAX" Lück, onkelpax-git[at]yahoo.de + */ +public interface Psapi extends StdCallLibrary { + Psapi INSTANCE = Native.loadLibrary("psapi", Psapi.class, W32APIOptions.DEFAULT_OPTIONS); + + /** + * Retrieves the fully qualified path for the file containing the specified + * module. + * + * @param process + * A handle to the process that contains the module. + * @param module + * A handle to the module. If this parameter is NULL, + * GetModuleFileNameEx returns the path of the executable file of + * the process specified in hProcess. + * @param lpFilename + * A pointer to a buffer that receives the fully qualified path + * to the module. If the size of the file name is larger than the + * value of the nSize parameter, the function succeeds but the + * file name is truncated and null-terminated. + * @param nSize + * The size of the lpFilename buffer, in characters. + * @return If the function succeeds, the return value specifies the length + * of the string copied to the buffer. If the function fails, the + * return value is zero. To get extended error information, call + * {@link Kernel32Util#getLastErrorMessage()}. + */ + int GetModuleFileNameExA(HANDLE process, HANDLE module, byte[] lpFilename, int nSize); + + /** + * Retrieves the fully qualified path for the file containing the specified + * module. + * + * @param process + * A handle to the process that contains the module. + * @param module + * A handle to the module. If this parameter is NULL, + * GetModuleFileNameEx returns the path of the executable file of + * the process specified in hProcess. + * @param lpFilename + * A pointer to a buffer that receives the fully qualified path + * to the module. If the size of the file name is larger than the + * value of the nSize parameter, the function succeeds but the + * file name is truncated and null-terminated. + * @param nSize + * The size of the lpFilename buffer, in characters. + * @return If the function succeeds, the return value specifies the length + * of the string copied to the buffer. If the function fails, the + * return value is zero. To get extended error information, call + * {@link Kernel32Util#getLastErrorMessage()}. + */ + int GetModuleFileNameExW(HANDLE process, HANDLE module, char[] lpFilename, int nSize); + + /** + * Retrieves the fully qualified path for the file containing the specified + * module. + * + * @param process + * A handle to the process that contains the module. + * @param module + * A handle to the module. If this parameter is NULL, + * GetModuleFileNameEx returns the path of the executable file of + * the process specified in hProcess. + * @param lpFilename + * A pointer to a buffer that receives the fully qualified path + * to the module. If the size of the file name is larger than the + * value of the nSize parameter, the function succeeds but the + * file name is truncated and null-terminated. + * @param nSize + * The size of the lpFilename buffer, in characters. + * @return If the function succeeds, the return value specifies the length + * of the string copied to the buffer. If the function fails, the + * return value is zero. To get extended error information, call + * {@link Kernel32Util#getLastErrorMessage()}. + */ + int GetModuleFileNameEx(HANDLE process, HANDLE module, Pointer lpFilename, int nSize); + + /** + * + * The EnumProcessModules function is primarily designed for use by + * debuggers and similar applications that must extract module information + * from another process.
    + * If the module list in the target process is corrupted or not yet + * initialized, or if the module list changes during the function call as a + * result of DLLs being loaded or unloaded, EnumProcessModules may fail or + * return incorrect information.
    + * It is a good idea to specify a large array of HMODULE values, because it + * is hard to predict how many modules there will be in the process at the + * time you call EnumProcessModules.
    + * To determine if the lphModule array is too small to hold all module + * handles for the process, compare the value returned in lpcbNeeded with + * the value specified in cb.
    + * If lpcbNeeded is greater than cb, increase the size of the array and call + * EnumProcessModules again. To determine how many modules were enumerated + * by the call to EnumProcessModules, divide the resulting value in the + * lpcbNeeded parameter by sizeof(HMODULE).
    + * The EnumProcessModules function does not retrieve handles for modules + * that were loaded with the LOAD_LIBRARY_AS_DATAFILE or similar flags. For + * more information, see LoadLibraryEx.
    + * Do not call CloseHandle on any of the handles returned by this function. + * The information comes from a snapshot, so there are no resources to be + * freed.
    + * If this function is called from a 32-bit application running on WOW64, it + * can only enumerate the modules of a 32-bit process.
    + * If the process is a 64-bit process, this function fails and the last + * error code is ERROR_PARTIAL_COPY (299).
    + * To take a snapshot of specified processes and the heaps, modules, and + * threads used by these processes, use the CreateToolhelp32Snapshot + * function.
    + * Starting with Windows 7 and Windows Server 2008 R2, Psapi.h establishes + * version numbers for the PSAPI functions.
    + * The PSAPI version number affects the name used to call the function and + * the library that a program must load.
    + * If PSAPI_VERSION is 2 or greater, this function is defined as + * K32EnumProcessModules in Psapi.h and exported in Kernel32.lib and + * Kernel32.dll.
    + * If PSAPI_VERSION is 1, this function is defined as EnumProcessModules in + * Psapi.h and exported in Psapi.lib and Psapi.dll as a wrapper that calls + * K32EnumProcessModules.
    + * Programs that must run on earlier versions of Windows as well as Windows + * 7 and later versions should always call this function as + * EnumProcessModules.
    + * To ensure correct resolution of symbols, add Psapi.lib to the TARGETLIBS + * macro and compile the program with -DPSAPI_VERSION=1.
    + * To use run-time dynamic linking, load Psapi.dll. + * + * @param hProcess + * A handle to the process. + * @param lphModule + * An array that receives the list of module handles. + * @param cb + * The size of the lphModule array, in bytes. + * @param lpcbNeeded + * The number of bytes required to store all module handles in + * the lphModule array. + * @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. + * @see MSDN/a> + */ + boolean EnumProcessModules(HANDLE hProcess, HMODULE[] lphModule, int cb, IntByReference lpcbNeeded); + + /** + * To get information for the calling process, pass the handle returned by + * GetCurrentProcess.
    + * The GetModuleInformation function does not retrieve information for + * modules that were loaded with the LOAD_LIBRARY_AS_DATAFILE flag.
    + * For more information, see LoadLibraryEx.
    + * Starting with Windows 7 and Windows Server 2008 R2, Psapi.h establishes + * version numbers for the PSAPI functions.
    + * The PSAPI version number affects the name used to call the function and + * the library that a program must load.
    + * If PSAPI_VERSION is 2 or greater, this function is defined as + * K32GetModuleInformation in Psapi.h and exported in Kernel32.lib and + * Kernel32.dll.
    + * If PSAPI_VERSION is 1, this function is defined as + * K32GetModuleInformation in Psapi.h and exported in Psapi.lib and + * Psapi.dll as a wrapper that calls K32GetModuleInformation.
    + * Programs that must run on earlier versions of Windows as well as Windows + * 7 and later versions should always call this function as + * K32GetModuleInformation.
    + * To ensure correct resolution of symbols, add Psapi.lib to the TARGETLIBS + * macro and compile the program with -DPSAPI_VERSION=1.
    + * To use run-time dynamic linking, load Psapi.dll. + * + * @param hProcess + * A handle to the process that contains the module. The handle + * must have the PROCESS_QUERY_INFORMATION and PROCESS_VM_READ + * access rights. For more information, see Process Security and + * Access Rights. + * @param hModule + * A handle to the module. + * + * @param lpmodinfo + * A pointer to the MODULEINFO structure that receives + * information about the module. + * @param cb + * The size of the MODULEINFO structure, in bytes. + * @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. + * @see
    MSDN + */ + boolean GetModuleInformation(HANDLE hProcess, HMODULE hModule, MODULEINFO lpmodinfo, int cb); + + /** + * @param hProcess + * A handle to the process. The handle must have the + * PROCESS_QUERY_INFORMATION or PROCESS_QUERY_LIMITED_INFORMATION + * access right. For more information, see Process Security and + * Access Rights.
    + * Windows Server 2003 and Windows XP: The handle must have the + * PROCESS_QUERY_INFORMATION access right. + * @param lpImageFileName + * A pointer to a buffer that receives the full path to the + * executable file. + * @param nSize + * The size of the lpImageFileName buffer, in characters. + * @return If the function succeeds, the return value specifies the length + * of the string copied to the buffer. If the function fails, the + * return value is zero. To get extended error information, call + * GetLastError. + * @see MSDN + */ + int GetProcessImageFileName(HANDLE hProcess, char[] lpImageFileName, int nSize); + + + /** + * Retrieves the performance values contained in the + * {@link PERFORMANCE_INFORMATION} structure. + * + * @param pPerformanceInformation + * A pointer to a {@link PERFORMANCE_INFORMATION} structure that + * receives the performance information. + * @param cb + * The size of the {@link PERFORMANCE_INFORMATION} structure, in + * bytes. + * @return If the function succeeds, the return value is TRUE. If the + * function fails, the return value is FALSE. To get extended error + * information, call {@link Kernel32Util#getLastErrorMessage()}. + * @see MSDN + */ + boolean GetPerformanceInfo(PERFORMANCE_INFORMATION pPerformanceInformation, int cb); + + class MODULEINFO extends Structure { + public static final List FIELDS = createFieldsOrder("lpBaseOfDll", "SizeOfImage", "EntryPoint"); + + public Pointer EntryPoint; + public Pointer lpBaseOfDll; + public int SizeOfImage; + + @Override + protected List getFieldOrder() { + return FIELDS; + } + } + + class PERFORMANCE_INFORMATION extends Structure { + public static final List FIELDS = createFieldsOrder("cb", "CommitTotal", "CommitLimit", + "CommitPeak", "PhysicalTotal", "PhysicalAvailable", "SystemCache", "KernelTotal", "KernelPaged", + "KernelNonpaged", "PageSize", "HandleCount", "ProcessCount", "ThreadCount"); + + public DWORD cb; + public SIZE_T CommitTotal; + public SIZE_T CommitLimit; + public SIZE_T CommitPeak; + public SIZE_T PhysicalTotal; + public SIZE_T PhysicalAvailable; + public SIZE_T SystemCache; + public SIZE_T KernelTotal; + public SIZE_T KernelPaged; + public SIZE_T KernelNonpaged; + public SIZE_T PageSize; + public DWORD HandleCount; + public DWORD ProcessCount; + public DWORD ThreadCount; + + @Override + protected List getFieldOrder() { + return FIELDS; + } + } +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Rasapi32.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Rasapi32.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Rasapi32.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Rasapi32.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2011 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; @@ -33,7 +44,7 @@ * Rasapi32.dll Interface. */ public interface Rasapi32 extends StdCallLibrary { - Rasapi32 INSTANCE = (Rasapi32) Native.loadLibrary("Rasapi32", Rasapi32.class, W32APIOptions.UNICODE_OPTIONS); + Rasapi32 INSTANCE = Native.loadLibrary("Rasapi32", Rasapi32.class, W32APIOptions.DEFAULT_OPTIONS); /** * The RasDial function establishes a RAS connection between a RAS client and a RAS server. @@ -62,7 +73,7 @@ * If RasDial succeeds, it stores a handle to the RAS connection into *lphRasConn. * @return If the function succeeds, the return value is ERROR_SUCCESS. */ - public int RasDial(RASDIALEXTENSIONS.ByReference lpRasDialExtensions, String lpszPhonebook, RASDIALPARAMS.ByReference lpRasDialParams, int dwNotifierType, RasDialFunc2 lpvNotifier, HANDLEByReference lphRasConn); + int RasDial(RASDIALEXTENSIONS.ByReference lpRasDialExtensions, String lpszPhonebook, RASDIALPARAMS.ByReference lpRasDialParams, int dwNotifierType, RasDialFunc2 lpvNotifier, HANDLEByReference lphRasConn); /** * The RasEnumConnections function lists all active RAS connections. It returns each connection's handle and phone-book entry name. @@ -78,7 +89,7 @@ * Pointer to a variable that receives the number of RASCONN structures written to the buffer specified by lprasconn. * @return If the function succeeds, the return value is ERROR_SUCCESS. */ - public int RasEnumConnections(RASCONN[] lprasconn, IntByReference lpcb, IntByReference lpcConnections); + int RasEnumConnections(RASCONN[] lprasconn, IntByReference lpcb, IntByReference lpcConnections); /** * The RasGetConnectionStatistics function retrieves accumulated connection statistics for the specified connection. @@ -90,7 +101,7 @@ * On input, set the dwSize member of the structure to sizeof(RASCONNSTATUS) in order to identify the version of the structure being passed. * @return If the function succeeds, the return value is ERROR_SUCCESS. */ - public int RasGetConnectionStatistics(HANDLE hrasconn, RAS_STATS.ByReference lpStatistics); + int RasGetConnectionStatistics(HANDLE hrasconn, RAS_STATS.ByReference lpStatistics); /** * The RasGetConnectionStatistics function retrieves accumulated connection statistics for the specified connection. @@ -103,7 +114,7 @@ * On input, set the dwSize member of the structure to sizeof(RASCONNSTATUS) in order to identify the version of the structure being passed. * @return If the function succeeds, the return value is ERROR_SUCCESS. */ - public int RasGetConnectStatus(HANDLE hrasconn, RASCONNSTATUS.ByReference lprasconnstatus); + int RasGetConnectStatus(HANDLE hrasconn, RASCONNSTATUS.ByReference lprasconnstatus); /** * The RasGetCredentials function retrieves the user credentials associated with a specified RAS phone-book entry. @@ -121,7 +132,7 @@ * credential information to retrieve. When the function returns, dwMask indicates the members that were successfully retrieved. * @return If the function succeeds, the return value is ERROR_SUCCESS. */ - public int RasGetCredentials(String lpszPhonebook, String lpszEntry, RASCREDENTIALS.ByReference lpCredentials); + int RasGetCredentials(String lpszPhonebook, String lpszEntry, RASCREDENTIALS.ByReference lpCredentials); /** * The RasGetEntryProperties function retrieves the properties of a phone-book entry. @@ -145,7 +156,7 @@ * This parameter is unused. The calling function should set this parameter to NULL. * @return If the function succeeds, the return value is ERROR_SUCCESS. */ - public int RasGetEntryProperties(String lpszPhonebook, String lpszEntry, RASENTRY.ByReference lpRasEntry, IntByReference lpdwEntryInfoSize, Pointer lpbDeviceInfo, Pointer lpdwDeviceInfoSize); + int RasGetEntryProperties(String lpszPhonebook, String lpszEntry, RASENTRY.ByReference lpRasEntry, IntByReference lpdwEntryInfoSize, Pointer lpbDeviceInfo, Pointer lpdwDeviceInfoSize); /** * The RasGetProjectionInfo function obtains information about a remote access projection operation for a specified remote access @@ -164,7 +175,7 @@ * On output, this variable receives the size, in bytes, of the lpprojection buffer. * @return If the function succeeds, the return value is ERROR_SUCCESS. */ - public int RasGetProjectionInfo(HANDLE hrasconn, int rasprojection, Pointer lpprojection, IntByReference lpcb); + int RasGetProjectionInfo(HANDLE hrasconn, int rasprojection, Pointer lpprojection, IntByReference lpcb); /** * The RasHangUp function terminates a remote access connection. The connection is specified with a RAS connection handle. @@ -174,7 +185,7 @@ * Specifies the remote access connection to terminate. This is a handle returned from a previous call to RasDial or RasEnumConnections. * @return If the function succeeds, the return value is ERROR_SUCCESS. */ - public int RasHangUp(HANDLE hrasconn); + int RasHangUp(HANDLE hrasconn); /** * The RasSetEntryProperties function changes the connection information for an entry in the phone book or creates a new phone-book entry. @@ -199,7 +210,7 @@ * Specifies the size, in bytes, of the lpbDeviceInfo buffer. * @return If the function succeeds, the return value is ERROR_SUCCESS. */ - public int RasSetEntryProperties(String lpszPhonebook, String lpszEntry, RASENTRY.ByReference lpRasEntry, int dwEntryInfoSize, byte[] lpbDeviceInfo, int dwDeviceInfoSize); + int RasSetEntryProperties(String lpszPhonebook, String lpszEntry, RASENTRY.ByReference lpRasEntry, int dwEntryInfoSize, byte[] lpbDeviceInfo, int dwDeviceInfoSize); /** * The RasGetEntryDialParams function retrieves the connection information saved by the last successful call to the RasDial or @@ -218,7 +229,7 @@ * the specified entry. If the system has no password saved for this entry, lpfPassword is FALSE. * @return If the function succeeds, the return value is ERROR_SUCCESS. */ - public int RasGetEntryDialParams(String lpszPhonebook, RASDIALPARAMS.ByReference lprasdialparams, BOOLByReference lpfPassword); + int RasGetEntryDialParams(String lpszPhonebook, RASDIALPARAMS.ByReference lprasdialparams, BOOLByReference lpfPassword); /** * The RasGetErrorString function obtains an error message string for a specified RAS error value. @@ -232,5 +243,5 @@ * Specifies the size, in characters, of the buffer pointed to by lpszErrorString. * @return status */ - public int RasGetErrorString(int uErrorValue, char[] lpszErrorString, int cBufSize); + int RasGetErrorString(int uErrorValue, char[] lpszErrorString, int cBufSize); } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Rasapi32Util.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Rasapi32Util.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Rasapi32Util.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Rasapi32Util.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2011 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Secur32.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Secur32.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Secur32.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Secur32.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,19 +1,31 @@ /* Copyright (c) 2010 Daniel Doubrovkine, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * 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). * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.Native; import com.sun.jna.Pointer; +import com.sun.jna.Structure; import com.sun.jna.platform.win32.Sspi.CredHandle; import com.sun.jna.platform.win32.Sspi.CtxtHandle; import com.sun.jna.platform.win32.Sspi.PSecPkgInfo; @@ -30,7 +42,7 @@ * @author dblock[at]dblock.org */ public interface Secur32 extends StdCallLibrary { - Secur32 INSTANCE = (Secur32) Native.loadLibrary("Secur32", Secur32.class, W32APIOptions.UNICODE_OPTIONS); + Secur32 INSTANCE = Native.loadLibrary("Secur32", Secur32.class, W32APIOptions.DEFAULT_OPTIONS); /** * Specifies a format for a directory service object name. @@ -57,7 +69,7 @@ * @param len On input, the size of the buffer, on output the number of characters copied into the buffer, not including the terminating null character. * @return True if the function succeeds. False otherwise. */ - public boolean GetUserNameEx(int nameFormat, char[] lpNameBuffer, IntByReference len); + boolean GetUserNameEx(int nameFormat, char[] lpNameBuffer, IntByReference len); /** * The AcquireCredentialsHandle function acquires a handle to preexisting credentials @@ -94,7 +106,7 @@ * If the function succeeds, the function returns one of the SEC_I_ success codes. * If the function fails, the function returns one of the SEC_E_ error codes. */ - public int AcquireCredentialsHandle(String pszPrincipal, String pszPackage, + int AcquireCredentialsHandle(String pszPrincipal, String pszPackage, int fCredentialUse, LUID pvLogonID, Pointer pAuthData, Pointer pGetKeyFn, // TODO: SEC_GET_KEY_FN Pointer pvGetKeyArgument, CredHandle phCredential, @@ -161,7 +173,7 @@ * If the function succeeds, the function returns one of the SEC_I_ success codes. * If the function fails, the function returns one of the SEC_E_ error codes. */ - public int InitializeSecurityContext(CredHandle phCredential, CtxtHandle phContext, + int InitializeSecurityContext(CredHandle phCredential, CtxtHandle phContext, String pszTargetName, int fContextReq, int Reserved1, int TargetDataRep, SecBufferDesc pInput, int Reserved2, CtxtHandle phNewContext, SecBufferDesc pOutput, IntByReference pfContextAttr, @@ -176,7 +188,7 @@ * If the function succeeds, the return value is SEC_E_OK. * If the function fails, the return value is SEC_E_INVALID_HANDLE; */ - public int DeleteSecurityContext(CtxtHandle phContext); + int DeleteSecurityContext(CtxtHandle phContext); /** * The FreeCredentialsHandle function notifies the security system that the @@ -191,7 +203,7 @@ * If the function succeeds, the return value is SEC_E_OK. * If the function fails, the return value is SEC_E_INVALID_HANDLE; */ - public int FreeCredentialsHandle(CredHandle phCredential); + int FreeCredentialsHandle(CredHandle phCredential); /** * The AcceptSecurityContext function enables the server component of a transport @@ -235,7 +247,7 @@ * @return * This function returns one of SEC_* values. */ - public int AcceptSecurityContext(CredHandle phCredential, CtxtHandle phContext, + int AcceptSecurityContext(CredHandle phCredential, CtxtHandle phContext, SecBufferDesc pInput, int fContextReq, int TargetDataRep, CtxtHandle phNewContext, SecBufferDesc pOutput, IntByReference pfContextAttr, TimeStamp ptsTimeStamp); @@ -253,8 +265,7 @@ * If the function succeeds, the function returns SEC_E_OK. * If the function fails, it returns a nonzero error code. */ - public int EnumerateSecurityPackages(IntByReference pcPackages, - PSecPkgInfo ppPackageInfo); + int EnumerateSecurityPackages(IntByReference pcPackages, PSecPkgInfo ppPackageInfo); /** * The FreeContextBuffer function enables callers of security package functions to free a memory @@ -266,7 +277,7 @@ * If the function succeeds, the function returns SEC_E_OK. * If the function fails, it returns a nonzero error code. */ - public int FreeContextBuffer(Pointer buffer); + int FreeContextBuffer(Pointer buffer); /** * The QuerySecurityContextToken function obtains the access token for a client security context @@ -280,8 +291,7 @@ * If the function fails, it returns a nonzero error code. One possible error code return is * SEC_E_INVALID_HANDLE. */ - public int QuerySecurityContextToken(CtxtHandle phContext, - HANDLEByReference phToken); + int QuerySecurityContextToken(CtxtHandle phContext, HANDLEByReference phToken); /** * The ImpersonateSecurityContext function allows a server to impersonate a client by using @@ -296,7 +306,7 @@ * If the function fails, it returns a SEC_E_INVALID_HANDLE, SEC_E_NO_IMPERSONATION or * SEC_E_UNSUPPORTED_FUNCTION error code. */ - public int ImpersonateSecurityContext(CtxtHandle phContext); + int ImpersonateSecurityContext(CtxtHandle phContext); /** * Allows a security package to discontinue the impersonation of the caller and restore its @@ -309,5 +319,25 @@ * If the function succeeds, the return value is SEC_E_OK. * If the function fails, the return value can be either SEC_E_INVALID_HANDLE or SEC_E_UNSUPPORTED_FUNCTION. */ - public int RevertSecurityContext(CtxtHandle phContext); + int RevertSecurityContext(CtxtHandle phContext); + + /** + * Enables a transport application to query a security package for certain + * attributes of a security context. + * + * @param phContext + * A handle to the security context to be queried. + * @param ulAttribute + * Specifies the attribute of the context to be returned. This + * parameter can be one of the SECPKG_ATTR_* values defined in + * {@link Sspi}. + * @param pBuffer + * A pointer to a structure that receives the attributes. The + * type of structure pointed to depends on the value specified in + * the ulAttribute parameter. + * @return + * If the function succeeds, the return value is SEC_E_OK. + * If the function fails, the return value is a nonzero error code. + */ + int QueryContextAttributes(CtxtHandle phContext, int ulAttribute, Structure pBuffer); } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Secur32Util.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Secur32Util.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Secur32Util.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Secur32Util.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2010 Daniel Doubrovkine, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/SetupApi.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/SetupApi.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/SetupApi.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/SetupApi.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,16 +1,27 @@ -/* This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. +/* + * 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 java.util.Arrays; import java.util.List; import com.sun.jna.Native; @@ -29,22 +40,21 @@ */ public interface SetupApi extends StdCallLibrary { - SetupApi INSTANCE = (SetupApi) - Native.loadLibrary("setupapi", SetupApi.class, W32APIOptions.DEFAULT_OPTIONS); + SetupApi INSTANCE = Native.loadLibrary("setupapi", SetupApi.class, W32APIOptions.DEFAULT_OPTIONS); /** * The GUID_DEVINTERFACE_DISK device interface class is defined for hard disk storage devices. */ GUID GUID_DEVINTERFACE_DISK = new GUID("53F56307-B6BF-11D0-94F2-00A0C91EFB8B"); - + /** * Drivers for serial ports register instances of this device interface * class to notify the operating system and applications of the presence of * COM ports. */ GUID GUID_DEVINTERFACE_COMPORT = new GUID("86E0D1E0-8089-11D0-9CE4-08003E301F73"); - + /** * Return only the device that is associated with the system default device interface, if one is set, for the * specified device interface classes. @@ -82,7 +92,6 @@ * Removable. */ int CM_DEVCAP_REMOVABLE = 0x00000004; - /** make change in all hardware profiles */ int DICS_FLAG_GLOBAL = 0x00000001; @@ -93,24 +102,23 @@ /** * Open/Create/Delete device key. - * - * @see #SetupDiOpenDevRegKey + * + * @see #SetupDiOpenDevRegKey */ - int DIREG_DEV = 0x00000001; + /** * Open/Create/Delete driver key - * - * @see #SetupDiOpenDevRegKey + * + * @see #SetupDiOpenDevRegKey */ - int DIREG_DRV = 0x00000002; + /** * Delete both driver and Device key - * - * @see #SetupDiOpenDevRegKey + * + * @see #SetupDiOpenDevRegKey */ - int DIREG_BOTH = 0x00000004; /** @@ -124,7 +132,6 @@ */ int SPDRP_DEVICEDESC = 0x00000000; - /** * The SetupDiGetClassDevs function returns a handle to a device information set that contains requested device * information elements for a local computer. @@ -301,7 +308,7 @@ * The specified device instance must be registered before this function is called. However, be aware that the * operating system automatically registers PnP device instances. For information about how to register non-PnP * device instances, see SetupDiRegisterDeviceInfo. - * + * * @param deviceInfoSet * A handle to the device information set that contains a device information element that represents the * device for which to open a registry key. @@ -359,8 +366,8 @@ *

    * Call SetupDiEnumDeviceInterfaces to get a context structure for a device interface element (versus a device * information element). - * - * + * + * * @param deviceInfoSet * A handle to the device information set for which to return an {@link SP_DEVINFO_DATA} structure that * represents a device information element. @@ -388,14 +395,7 @@ } } - public SP_DEVICE_INTERFACE_DATA() { - cbSize = size(); - } - - public SP_DEVICE_INTERFACE_DATA(Pointer memory) { - super(memory); - read(); - } + public static final List FIELDS = createFieldsOrder("cbSize", "InterfaceClassGuid", "Flags", "Reserved"); /** * The size, in bytes, of the SP_DEVICE_INTERFACE_DATA structure. @@ -419,9 +419,19 @@ * Reserved. Do not use. */ public Pointer Reserved; - + + public SP_DEVICE_INTERFACE_DATA() { + cbSize = size(); + } + + public SP_DEVICE_INTERFACE_DATA(Pointer memory) { + super(memory); + read(); + } + + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "cbSize", "InterfaceClassGuid", "Flags", "Reserved" }); + return FIELDS; } } @@ -439,14 +449,7 @@ } } - public SP_DEVINFO_DATA() { - cbSize = size(); - } - - public SP_DEVINFO_DATA(Pointer memory) { - super(memory); - read(); - } + public static final List FIELDS = createFieldsOrder("cbSize", "InterfaceClassGuid", "DevInst", "Reserved"); /** * The size, in bytes, of the SP_DEVINFO_DATA structure. @@ -471,9 +474,19 @@ * Reserved. For internal use only. */ public Pointer Reserved; - + + public SP_DEVINFO_DATA() { + cbSize = size(); + } + + public SP_DEVINFO_DATA(Pointer memory) { + super(memory); + read(); + } + + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "cbSize", "InterfaceClassGuid", "DevInst", "Reserved" }); + return FIELDS; } } } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Shell32.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Shell32.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Shell32.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Shell32.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,20 +1,33 @@ /* Copyright (c) 2007, 2013 Timothy Wall, Markus Karg, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

    - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.Native; +import com.sun.jna.WString; import com.sun.jna.platform.win32.Guid.GUID; import com.sun.jna.platform.win32.WinDef.DWORD; +import com.sun.jna.platform.win32.WinDef.HICON; import com.sun.jna.platform.win32.WinDef.HWND; import com.sun.jna.platform.win32.WinDef.INT_PTR; import com.sun.jna.platform.win32.WinDef.UINT_PTR; @@ -28,9 +41,43 @@ * Shell32.dll Interface. */ public interface Shell32 extends ShellAPI, StdCallLibrary { - - Shell32 INSTANCE = (Shell32) Native.loadLibrary("shell32", Shell32.class, - W32APIOptions.UNICODE_OPTIONS); + /** The instance **/ + Shell32 INSTANCE = Native.loadLibrary("shell32", Shell32.class, W32APIOptions.DEFAULT_OPTIONS); + + /** + * No dialog box confirming the deletion of the objects will be displayed. + */ + int SHERB_NOCONFIRMATION = 0x00000001; + + /** + * No dialog box indicating the progress will be displayed. + */ + int SHERB_NOPROGRESSUI = 0x00000002; + + /** + * No sound will be played when the operation is complete. + */ + int SHERB_NOSOUND = 0x00000004; + + /** + *

    + * SEE_MASK_NOCLOSEPROCESS (0x00000040) + *

    + *

    + * Use to indicate that the hProcess member receives the + * process handle. This handle is typically used to allow an application to + * find out when a process created with terminates. In some cases, such as + * when execution is satisfied through a DDE conversation, no handle will be + * returned. The calling application is responsible for closing the handle + * when it is no longer needed. + *

    + */ + int SEE_MASK_NOCLOSEPROCESS = 0x00000040; + + /** + * Do not display an error message box if an error occurs. + */ + int SEE_MASK_FLAG_NO_UI = 0x00000400; /** * This function can be used to copy, move, rename, or delete a file system object. @@ -63,8 +110,7 @@ * @return * Returns standard HRESULT codes. */ - HRESULT SHGetFolderPath(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, - char[] pszPath); + HRESULT SHGetFolderPath(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, char[] pszPath); /** * Retrieves the full path of a known folder identified by the folder's KNOWNFOLDERID. This function replaces @@ -103,7 +149,7 @@ * @param ppshf A place to put the IShellFolder interface pointer * @return If the function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. */ - HRESULT SHGetDesktopFolder( PointerByReference ppshf ); + HRESULT SHGetDesktopFolder(PointerByReference ppshf); /** * Performs an operation on a specified file. @@ -181,8 +227,7 @@ * SE_ERR_PNF The specified path was not found. * SE_ERR_SHARE A sharing violation occurred. */ - INT_PTR ShellExecute(HWND hwnd, String lpOperation, String lpFile, String lpParameters, String lpDirectory, - int nShowCmd); + INT_PTR ShellExecute(HWND hwnd, String lpOperation, String lpFile, String lpParameters, String lpDirectory, int nShowCmd); /** * Retrieves the path of a special folder, identified by its CSIDL. @@ -201,22 +246,21 @@ */ boolean SHGetSpecialFolderPath(HWND owner, char[] path, int csidl, boolean create); - /** * SHAppBarMessage function * * @param dwMessage * Appbar message value to send. This parameter can be one of the following values. * {@link ShellAPI#ABM_NEW} Registers a new appbar and specifies the message identifier that the system should use to send notification messages to the appbar. - * {@link ShellAPI#ABM_REMOVE} Unregisters an appbar, removing the bar from the system's internal list. - * {@link ShellAPI#ABM_QUERYPOS} Requests a size and screen position for an appbar. + * {@link ShellAPI#ABM_REMOVE} Unregisters an appbar, removing the bar from the system's internal list. + * {@link ShellAPI#ABM_QUERYPOS} Requests a size and screen position for an appbar. * {@link ShellAPI#ABM_SETPOS} Sets the size and screen position of an appbar. - * {@link ShellAPI#ABM_GETSTATE} Retrieves the autohide and always-on-top states of the Windows taskbar. - * {@link ShellAPI#ABM_GETTASKBARPOS} Retrieves the bounding rectangle of the Windows taskbar. Note that this applies only to the system taskbar. Other objects, particularly toolbars supplied with third-party software, also can be present. As a result, some of the screen area not covered by the Windows taskbar might not be visible to the user. To retrieve the area of the screen not covered by both the taskbar and other app bars -- the working area available to your application --, use the GetMonitorInfo function. - * {@link ShellAPI#ABM_ACTIVATE} Notifies the system to activate or deactivate an appbar. The lParam member of the APPBARDATA pointed to by pData is set to TRUE to activate or FALSE to deactivate. - * {@link ShellAPI#ABM_GETAUTOHIDEBAR} Retrieves the handle to the autohide appbar associated with a particular edge of the screen. - * {@link ShellAPI#ABM_SETAUTOHIDEBAR} Registers or unregisters an autohide appbar for an edge of the screen. - * {@link ShellAPI#ABM_WINDOWPOSCHANGED} Notifies the system when an appbar's position has changed. + * {@link ShellAPI#ABM_GETSTATE} Retrieves the autohide and always-on-top states of the Windows taskbar. + * {@link ShellAPI#ABM_GETTASKBARPOS} Retrieves the bounding rectangle of the Windows taskbar. Note that this applies only to the system taskbar. Other objects, particularly toolbars supplied with third-party software, also can be present. As a result, some of the screen area not covered by the Windows taskbar might not be visible to the user. To retrieve the area of the screen not covered by both the taskbar and other app bars -- the working area available to your application --, use the GetMonitorInfo function. + * {@link ShellAPI#ABM_ACTIVATE} Notifies the system to activate or deactivate an appbar. The lParam member of the APPBARDATA pointed to by pData is set to TRUE to activate or FALSE to deactivate. + * {@link ShellAPI#ABM_GETAUTOHIDEBAR} Retrieves the handle to the autohide appbar associated with a particular edge of the screen. + * {@link ShellAPI#ABM_SETAUTOHIDEBAR} Registers or unregisters an autohide appbar for an edge of the screen. + * {@link ShellAPI#ABM_WINDOWPOSCHANGED} Notifies the system when an appbar's position has changed. * {@link ShellAPI#ABM_SETSTATE} Windows XP and later: Sets the state of the appbar's autohide and always-on-top attributes. * * @param pData @@ -237,5 +281,133 @@ * @see ABM_SETSTATE * */ - UINT_PTR SHAppBarMessage( DWORD dwMessage, APPBARDATA pData ); + UINT_PTR SHAppBarMessage(DWORD dwMessage, APPBARDATA pData); + + /** + * Empties the Recycle Bin on the specified drive. + * + * @param hwnd + * A handle to the parent window of any dialog boxes that might + * be displayed during the operation.
    + * This parameter can be NULL. + * @param pszRootPath + * a null-terminated string of maximum length MAX_PATH that + * contains the path of the root
    + * drive on which the Recycle Bin is located. This parameter can + * contain a string formatted with the drive,
    + * folder, and subfolder names, for example c:\windows\system\, + * etc. It can also contain an empty string or
    + * NULL. If this value is an empty string or NULL, all Recycle + * Bins on all drives will be emptied. + * @param dwFlags + * a bitwise combination of SHERB_NOCONFIRMATION, + * SHERB_NOPROGRESSUI and SHERB_NOSOUND.
    + * @return Returns S_OK (0) if successful, or a COM-defined error value + * otherwise.
    + */ + int SHEmptyRecycleBin(HANDLE hwnd, String pszRootPath, int dwFlags); + + /** + * @param lpExecInfo + *

    + * Type: SHELLEXECUTEINFO* + *

    + *

    + * A pointer to a + * SHELLEXECUTEINFO + * structure that contains and receives information + * about the application being executed. + *

    + * @return + *

    + * Returns TRUE if successful; otherwise, + * FALSE. Call + * GetLastError + * for extended error information. + *

    + */ + boolean ShellExecuteEx(ShellAPI.SHELLEXECUTEINFO lpExecInfo); + + /** + * SHGetSpecialFolderLocation function for getting PIDL reference to My Computer etc + * + * @param hwndOwner + * Reserved. + * @param nFolder + * A CSIDL value that identifies the folder of interest. + * @param ppidl + * A PIDL specifying the folder's location relative to the root of the namespace (the desktop). It is the responsibility of the calling application to free the returned IDList by using CoTaskMemFree. + * + * @return If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. + * + */ + HRESULT SHGetSpecialFolderLocation(WinDef.HWND hwndOwner, int nFolder, PointerByReference ppidl); + + /** + * @param lpszFile + * Type: LPCTSTR
    + * The name of an executable file, DLL, or icon file from which + * icons will be extracted. + * @param nIconIndex + * Type: int
    + * The zero-based index of the first icon to extract. For + * example, if this value is zero, the function extracts the + * first icon in the specified file.
    + * If this value is -1 and phiconLarge and phiconSmall are both + * NULL, the function returns the total number of icons in the + * specified file.
    + * If the file is an executable file or DLL, the return value is + * the number of RT_GROUP_ICON resources.
    + * If the file is an .ico file, the return value is 1. If this + * value is a negative number and either phiconLarge or + * phiconSmall is not NULL, the function begins by extracting the + * icon whose resource identifier is equal to the absolute value + * of nIconIndex. For example, use -3 to extract the icon whose + * resource identifier is 3. + * @param phiconLarge + * Type: HICON*
    + * An array of icon handles that receives handles to the large + * icons extracted from the file. If this parameter is NULL, no + * large icons are extracted from the file. + * @param phiconSmall + * Type: HICON*
    + * An array of icon handles that receives handles to the small + * icons extracted from the file. If this parameter is NULL, no + * small icons are extracted from the file. + * @param nIcons + * Type: UINT
    + * The number of icons to be extracted from the file. + * @return Type: UINT
    + * If the nIconIndex parameter is -1, the phiconLarge parameter is + * NULL, and the phiconSmall parameter is NULL, then the return + * value is the number of icons contained in the specified file. + * Otherwise, the return value is the number of icons successfully + * extracted from the file. + * @see MSDN + */ + int ExtractIconEx(String lpszFile, int nIconIndex, HICON[] phiconLarge, HICON[] phiconSmall, int nIcons); + + /** + * Retrieves the application-defined, explicit Application User Model ID (AppUserModelID) for the current process. + * + * @param ppszAppID + * A pointer that receives the address of the AppUserModelID assigned to the process. The caller is responsible for freeing this string with {@link Ole32#CoTaskMemFree} when it is no longer needed. + * @return If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. + * @see MSDN + */ + HRESULT GetCurrentProcessExplicitAppUserModelID(PointerByReference ppszAppID); + + /** + * Specifies a unique application-defined Application User Model ID (AppUserModelID) that identifies the current process to the taskbar. This identifier allows an application to group its associated processes and windows under a single taskbar button. + * + * @param appID + * The AppUserModelID to assign to the current process. + * @return If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. + * @see MSDN + */ + HRESULT SetCurrentProcessExplicitAppUserModelID(WString appID); + } + diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Shell32Util.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Shell32Util.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Shell32Util.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Shell32Util.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2010, 2013 Daniel Doubrovkine, Markus Karg, 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; @@ -16,7 +27,6 @@ import com.sun.jna.platform.win32.Guid.GUID; import com.sun.jna.platform.win32.WinDef.DWORD; import com.sun.jna.platform.win32.WinDef.HWND; -import com.sun.jna.platform.win32.WinDef.LPVOID; import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.platform.win32.WinNT.HRESULT; import com.sun.jna.ptr.PointerByReference; @@ -27,7 +37,7 @@ * @author markus[at]headcrashing[dot]eu */ public abstract class Shell32Util { - + /** * Get a special folder path. * @param hwnd @@ -41,15 +51,15 @@ */ public static String getFolderPath(HWND hwnd, int nFolder, DWORD dwFlags) { char[] pszPath = new char[WinDef.MAX_PATH]; - HRESULT hr = Shell32.INSTANCE.SHGetFolderPath(hwnd, - nFolder, null, dwFlags, + HRESULT hr = Shell32.INSTANCE.SHGetFolderPath(hwnd, + nFolder, null, dwFlags, pszPath); if (! hr.equals(W32Errors.S_OK)) { throw new Win32Exception(hr); } return Native.toString(pszPath); } - + /** * Get a special folder path. * @param nFolder @@ -60,9 +70,9 @@ public static String getFolderPath(int nFolder) { return getFolderPath(null, nFolder, ShlObj.SHGFP_TYPE_CURRENT); } - + /** - * Retrieves the full path of a known folder identified by the folder's KNOWNFOLDERID. This function replaces + * Retrieves the full path of a known folder identified by the folder's KNOWNFOLDERID. This function replaces * {@link #getFolderPath}. That older function is now simply a wrapper for getKnownFolderPath * @param guid the KNOWNFOLDERS GUID as defined in {@link KnownFolders} * @return the path of the known folder. The returned path does not include a trailing backslash. For example, diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/ShellAPI.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/ShellAPI.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/ShellAPI.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/ShellAPI.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,32 +1,44 @@ /* 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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 java.util.Arrays; import java.util.List; import com.sun.jna.Platform; import com.sun.jna.Pointer; import com.sun.jna.Structure; -import com.sun.jna.WString; +import com.sun.jna.TypeMapper; import com.sun.jna.platform.win32.WinDef.DWORD; +import com.sun.jna.platform.win32.WinDef.HINSTANCE; import com.sun.jna.platform.win32.WinDef.HWND; import com.sun.jna.platform.win32.WinDef.LPARAM; import com.sun.jna.platform.win32.WinDef.RECT; import com.sun.jna.platform.win32.WinDef.UINT; import com.sun.jna.platform.win32.WinNT.HANDLE; -import com.sun.jna.platform.win32.WinNT.PSID; +import com.sun.jna.platform.win32.WinReg.HKEY; import com.sun.jna.win32.StdCallLibrary; +import com.sun.jna.win32.W32APITypeMapper; /** * Ported from ShellAPI.h. @@ -36,12 +48,13 @@ public interface ShellAPI extends StdCallLibrary { int STRUCTURE_ALIGNMENT = Platform.is64Bit() ? Structure.ALIGN_DEFAULT : Structure.ALIGN_NONE; - + TypeMapper TYPE_MAPPER = Boolean.getBoolean("w32.ascii") ? W32APITypeMapper.ASCII : W32APITypeMapper.UNICODE; + int FO_MOVE = 0x0001; int FO_COPY = 0x0002; int FO_DELETE = 0x0003; int FO_RENAME = 0x0004; - + int FOF_MULTIDESTFILES = 0x0001; int FOF_CONFIRMMOUSE = 0x0002; int FOF_SILENT = 0x0004; // don't display progress UI (confirm prompts may be displayed still) @@ -59,18 +72,21 @@ int FOF_WANTNUKEWARNING = 0x4000; // during delete operation, warn if nuking instead of recycling (partially overrides FOF_NOCONFIRMATION) int FOF_NORECURSEREPARSE = 0x8000; // deprecated; the operations engine always does the right thing on FolderLink objects (symlinks, reparse points, folder shortcuts) int FOF_NO_UI = (FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_NOCONFIRMMKDIR); // don't display any UI at all - + int PO_DELETE = 0x0013; // printer is being deleted int PO_RENAME = 0x0014; // printer is being renamed int PO_PORTCHANGE = 0x0020; // port this printer connected to is being changed int PO_REN_PORT = 0x0034; // PO_RENAME and PO_PORTCHANGE at same time. /** - * Contains information that the SHFileOperation function uses to perform file operations. + * Contains information that the SHFileOperation function uses to perform file operations. */ public static class SHFILEOPSTRUCT extends Structure { + public static final List FIELDS = createFieldsOrder( + "hwnd", "wFunc", "pFrom", "pTo", "fFlags", "fAnyOperationsAborted", "pNameMappings", "lpszProgressTitle"); + /** - * A window handle to the dialog box to display information about + * A window handle to the dialog box to display information about * the status of the file operation. */ public HANDLE hwnd; @@ -79,37 +95,38 @@ */ public int wFunc; /** - * A pointer to one or more source file names, double null-terminated. + * A pointer to one or more source file names, double null-terminated. */ - public WString pFrom; + public String pFrom; /** * A pointer to the destination file or directory name. */ - public WString pTo; + public String pTo; /** * Flags that control the file operation. */ public short fFlags; /** - * When the function returns, this member contains TRUE if any file operations - * were aborted before they were completed; otherwise, FALSE. An operation can - * be manually aborted by the user through UI or it can be silently aborted by + * When the function returns, this member contains TRUE if any file operations + * were aborted before they were completed; otherwise, FALSE. An operation can + * be manually aborted by the user through UI or it can be silently aborted by * the system if the FOF_NOERRORUI or FOF_NOCONFIRMATION flags were set. */ public boolean fAnyOperationsAborted; /** - * When the function returns, this member contains a handle to a name mapping - * object that contains the old and new names of the renamed files. This member - * is used only if the fFlags member includes the FOF_WANTMAPPINGHANDLE flag. + * When the function returns, this member contains a handle to a name mapping + * object that contains the old and new names of the renamed files. This member + * is used only if the fFlags member includes the FOF_WANTMAPPINGHANDLE flag. */ public Pointer pNameMappings; /** - * A pointer to the title of a progress dialog box. This is a null-terminated string. + * A pointer to the title of a progress dialog box. This is a null-terminated string. */ - public WString lpszProgressTitle; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "hwnd", "wFunc", "pFrom", "pTo", "fFlags", "fAnyOperationsAborted", "pNameMappings", "lpszProgressTitle" }); + public String lpszProgressTitle; + + @Override + protected List getFieldOrder() { + return FIELDS; } /** Use this to encode pFrom/pTo paths. @@ -124,11 +141,9 @@ } return encoded + "\0"; } - - } - - /** + + /** * Appbar message value to send. This parameter can be one of the following * values. */ @@ -175,11 +190,11 @@ /** Left edge. */ int ABE_LEFT = 0; /** Top edge. */ - int ABE_TOP = 1; + int ABE_TOP = 1; /** Right edge. */ - int ABE_RIGHT = 2; + int ABE_RIGHT = 2; /** Bottom edge. */ - int ABE_BOTTOM = 3; + int ABE_BOTTOM = 3; /** * Contains information about a system appbar message. @@ -188,6 +203,8 @@ public static class ByReference extends APPBARDATA implements Structure.ByReference { } + public static final List FIELDS = createFieldsOrder("cbSize", "hWnd", "uCallbackMessage", "uEdge", "rc", "lParam"); + public DWORD cbSize; public HWND hWnd; public UINT uCallbackMessage; @@ -204,9 +221,847 @@ } @Override - protected List getFieldOrder() { - return Arrays.asList("cbSize", "hWnd", "uCallbackMessage", "uEdge", "rc", "lParam"); + protected List getFieldOrder() { + return FIELDS; } } + /** + *

    + * Contains information used by + * ShellExecuteEx. + *

    + * + *
    +	 * typedef struct _SHELLEXECUTEINFO {
    +	 *   DWORD     cbSize;
    +	 *   ULONG     fMask;
    +	 *   HWND      hwnd;
    +	 *   LPCTSTR   lpVerb;
    +	 *   LPCTSTR   lpFile;
    +	 *   LPCTSTR   lpParameters;
    +	 *   LPCTSTR   lpDirectory;
    +	 *   int       nShow;
    +	 *   HINSTANCE hInstApp;
    +	 *   LPVOID    lpIDList;
    +	 *   LPCTSTR   lpClass;
    +	 *   HKEY      hkeyClass;
    +	 *   DWORD     dwHotKey;
    +	 *   union {
    +	 *     HANDLE hIcon;
    +	 *     HANDLE hMonitor;
    +	 *   } DUMMYUNIONNAME;
    +	 *   HANDLE    hProcess;
    +	 * } SHELLEXECUTEINFO, *LPSHELLEXECUTEINFO;
    +	 * 
    + * + *

    Remarks

    + *

    + * The SEE_MASK_NOASYNC flag must be specified if the + * thread calling + * ShellExecuteEx + * does not have a message loop or if the thread or process will terminate + * soon after ShellExecuteEx returns. Under such + * conditions, the calling thread will not be available to complete the DDE + * conversation, so it is important that ShellExecuteEx + * complete the conversation before returning control to the calling + * application. Failure to complete the conversation can result in an + * unsuccessful launch of the document. + *

    + *

    + * If the calling thread has a message loop and will exist for some time + * after the call to + * ShellExecuteEx + * returns, the SEE_MASK_NOASYNC flag is optional. If the + * flag is omitted, the calling thread's message pump will be used to + * complete the DDE conversation. The calling application regains control + * sooner, since the DDE conversation can be completed in the background. + *

    + *

    + * When populating the most frequently used program list using the + * SEE_MASK_FLAG_LOG_USAGE flag in fMask, + * counts are made differently for the classic and Windows XP-style + * Start menus. The classic style menu only counts hits to the shortcuts in + * the Program menu. The Windows XP-style menu counts both hits to the + * shortcuts in the Program menu and hits to those shortcuts' targets + * outside of the Program menu. Therefore, setting lpFile + * to myfile.exe would affect the count for the Windows XP-style menu + * regardless of whether that file was launched directly or through a + * shortcut. The classic style-which would require lpFile + * to contain a .lnk file name-would not be affected. + *

    + *

    + * To include double quotation marks in lpParameters, + * enclose each mark in a pair of quotation marks, as in the following + * example. + *

    + *

    + *

    +	 * sei.lpParameters = "An example: \"\"\"quoted text\"\"\"";
    +	 * 
    + *

    + *

    + * In this case, the application receives three parameters: An, + * example:, and "quoted text". + *

    + */ + public class SHELLEXECUTEINFO extends Structure { + public static final List FIELDS = createFieldsOrder("cbSize", "fMask", "hwnd", "lpVerb", "lpFile", "lpParameters", + "lpDirectory", "nShow", "hInstApp", "lpIDList", "lpClass", "hKeyClass", "dwHotKey", "hMonitor", + "hProcess"); + /** + *

    + * Type: DWORD + *

    + *

    + * Required. The size of this structure, in bytes. + *

    + */ + public int cbSize = size(); + + /** + *

    + * Type: ULONG + *

    + *

    + * Flags that indicate the content and validity of the other structure + * members; a combination of the following values: + *

    + *
    + *
    + *

    + * SEE_MASK_DEFAULT (0x00000000) + *

    + *
    + *
    + *

    + * Use default values. + *

    + *
    + *
    + *

    + * SEE_MASK_CLASSNAME (0x00000001) + *

    + *
    + *
    + *

    + * Use the class name given by the lpClass member. If + * both SEE_MASK_CLASSKEY and SEE_MASK_CLASSNAME are set, the class key + * is used. + *

    + *
    + *
    + *

    + * SEE_MASK_CLASSKEY (0x00000003) + *

    + *
    + *
    + *

    + * Use the class key given by the hkeyClass member. If + * both SEE_MASK_CLASSKEY and SEE_MASK_CLASSNAME are set, the class key + * is used. + *

    + *
    + *
    + *

    + * SEE_MASK_IDLIST (0x00000004) + *

    + *
    + *
    + *

    + * Use the item identifier list given by the lpIDList + * member. The lpIDList member must point to an + * structure. + *

    + *
    + *
    + *

    + * SEE_MASK_INVOKEIDLIST (0x0000000C) + *

    + *
    + *
    + *

    + * Use the interface of the selected item's . Use either + * lpFile to identify the item by its file system path + * or lpIDList to identify the item by its PIDL. This + * flag allows applications to use to invoke verbs from shortcut menu + * extensions instead of the static verbs listed in the registry. + *

    + *
    Note + *   SEE_MASK_INVOKEIDLIST overrides and implies + * SEE_MASK_IDLIST.
    + *
    + *

    + * SEE_MASK_ICON (0x00000010) + *

    + *
    + *
    + *

    + * Use the icon given by the hIcon member. This flag + * cannot be combined with SEE_MASK_HMONITOR. + *

    + *
    Note  This flag is used + * only in Windows XP and earlier. It is ignored as of + * Windows Vista.
    + *
    + *

    + * SEE_MASK_HOTKEY (0x00000020) + *

    + *
    + *
    + *

    + * Use the keyboard shortcut given by the dwHotKey + * member. + *

    + *
    + *
    + *

    + * SEE_MASK_NOCLOSEPROCESS (0x00000040) + *

    + *
    + *
    + *

    + * Use to indicate that the hProcess member receives + * the process handle. This handle is typically used to allow an + * application to find out when a process created with terminates. In + * some cases, such as when execution is satisfied through a DDE + * conversation, no handle will be returned. The calling application is + * responsible for closing the handle when it is no longer needed. + *

    + *
    + *
    + *

    + * SEE_MASK_CONNECTNETDRV (0x00000080) + *

    + *
    + *
    + *

    + * Validate the share and connect to a drive letter. This enables + * reconnection of disconnected network drives. The + * lpFile member is a UNC path of a file on a network. + *

    + *
    + *
    + *

    + * SEE_MASK_NOASYNC (0x00000100) + *

    + *
    + *
    + *

    + * Wait for the execute operation to complete before returning. This + * flag should be used by callers that are using ShellExecute forms that + * might result in an async activation, for example DDE, and create a + * process that might be run on a background thread. (Note: runs on a + * background thread by default if the caller's threading model is not + * Apartment.) Calls to ShellExecuteEx from processes + * already running on background threads should always pass this flag. + * Also, applications that exit immediately after calling + * ShellExecuteEx should specify this flag. + *

    + *

    + * If the execute operation is performed on a background thread and the + * caller did not specify the SEE_MASK_ASYNCOK flag, then the calling + * thread waits until the new process has started before returning. This + * typically means that either has been called, the DDE communication + * has completed, or that the custom execution delegate has notified + * that it is done. If the SEE_MASK_WAITFORINPUTIDLE flag is specified, + * then ShellExecuteEx calls and waits for the new + * process to idle before returning, with a maximum timeout of 1 minute. + *

    + *

    + * For further discussion on when this flag is necessary, see the + * Remarks section. + *

    + *
    + *
    + *

    + * SEE_MASK_FLAG_DDEWAIT (0x00000100) + *

    + *
    + *
    + *

    + * Do not use; use SEE_MASK_NOASYNC instead. + *

    + *
    + *
    + *

    + * SEE_MASK_DOENVSUBST (0x00000200) + *

    + *
    + *
    + *

    + * Expand any environment variables specified in the string given by the + * lpDirectory or lpFile member. + *

    + *
    + *
    + *

    + * SEE_MASK_FLAG_NO_UI (0x00000400) + *

    + *
    + *
    + *

    + * Do not display an error message box if an error occurs. + *

    + *
    + *
    + *

    + * SEE_MASK_UNICODE (0x00004000) + *

    + *
    + *
    + *

    + * Use this flag to indicate a Unicode application. + *

    + *
    + *
    + *

    + * SEE_MASK_NO_CONSOLE (0x00008000) + *

    + *
    + *
    + *

    + * Use to inherit the parent's console for the new process instead of + * having it create a new console. It is the opposite of using a + * CREATE_NEW_CONSOLE flag with . + *

    + *
    + *
    + *

    + * SEE_MASK_ASYNCOK (0x00100000) + *

    + *
    + *
    + *

    + * The execution can be performed on a background thread and the call + * should return immediately without waiting for the background thread + * to finish. Note that in certain cases ignores this flag and waits for + * the process to finish before returning. + *

    + *
    + *
    + *

    + * SEE_MASK_NOQUERYCLASSSTORE (0x01000000) + *

    + *
    + *
    + *

    + * Not used. + *

    + *
    + *
    + *

    + * SEE_MASK_HMONITOR (0x00200000) + *

    + *
    + *
    + *

    + * Use this flag when specifying a monitor on multi-monitor systems. The + * monitor is specified in the hMonitor member. This + * flag cannot be combined with SEE_MASK_ICON. + *

    + *
    + *
    + *

    + * SEE_MASK_NOZONECHECKS (0x00800000) + *

    + *
    + *
    + *

    + * Introduced in Windows XP. Do not perform a zone + * check. This flag allows to bypass zone checking put into place by . + *

    + *
    + *
    + *

    + * SEE_MASK_WAITFORINPUTIDLE (0x02000000) + *

    + *
    + *
    + *

    + * After the new process is created, wait for the process to become idle + * before returning, with a one minute timeout. See for more details. + *

    + *
    + *
    + *

    + * SEE_MASK_FLAG_LOG_USAGE (0x04000000) + *

    + *
    + *
    + *

    + * Introduced in Windows XP. Keep track of the + * number of times this application has been launched. Applications with + * sufficiently high counts appear in the Start Menu's list of most + * frequently used programs. + *

    + *
    + *
    + *

    + * SEE_MASK_FLAG_HINST_IS_SITE (0x08000000) + *

    + *
    + *
    + *

    + * Introduced in Windows 8. The + * hInstApp member is used to specify the of an object + * that implements . This object will be used as a site pointer. The + * site pointer is used to provide services to the function, the handler + * binding process, and invoked verb handlers. + *

    + *
    + *
    + */ + public int fMask; + + /** + *

    + * Type: HWND + *

    + *

    + * Optional. A handle to the parent window, used to display any message + * boxes that the system might produce while executing this function. + * This value can be NULL. + *

    + */ + public HWND hwnd; + + /** + *

    + * Type: LPCTSTR + *

    + * + *
    + *

    + * A string, referred to as a verb, that specifies the action + * to be performed. The set of available verbs depends on the particular + * file or folder. Generally, the actions available from an object's + * shortcut menu are available verbs. This parameter can be + * NULL, in which case the default verb is used if + * available. If not, the "open" verb is used. If neither verb is + * available, the system uses the first verb listed in the registry. The + * following verbs are commonly used: + *

    + *
    + *
    + *

    + * edit + *

    + *
    + *
    + *

    + * Launches an editor and opens the document for editing. If + * lpFile is not a document file, the function will + * fail. + *

    + *
    + *
    + *

    + * explore + *

    + *
    + *
    + *

    + * Explores the folder specified by lpFile. + *

    + *
    + *
    + *

    + * find + *

    + *
    + *
    + *

    + * Initiates a search starting from the specified directory. + *

    + *
    + *
    + *

    + * open + *

    + *
    + *
    + *

    + * Opens the file specified by the lpFile parameter. + * The file can be an executable file, a document file, or a folder. + *

    + *
    + *
    + *

    + * print + *

    + *
    + *
    + *

    + * Prints the document file specified by lpFile. If + * lpFile is not a document file, the function will + * fail. + *

    + *
    + *
    + *

    + * properties + *

    + *
    + *
    + *

    + * Displays the file or folder's properties. + *

    + *
    + *
    + */ + public String lpVerb; + + /** + *

    + * Type: LPCTSTR + *

    + *

    + * The address of a null-terminated string that specifies the name of + * the file or object on which will perform the action specified by the + * lpVerb parameter. The system registry verbs that are + * supported by the ShellExecuteEx function include + * "open" for executable files and document files and "print" for + * document files for which a print handler has been registered. Other + * applications might have added Shell verbs through the system + * registry, such as "play" for .avi and .wav files. To specify a Shell + * namespace object, pass the fully qualified parse name and set the + * SEE_MASK_INVOKEIDLIST flag in the + * fMask parameter. + *

    + *
    Note  If the + * SEE_MASK_INVOKEIDLIST flag is set, you can use + * either lpFile or lpIDList to + * identify the item by its file system path or its PIDL respectively. + * One of the two values-lpFile or + * lpIDList-must be set.
    + *
    Note  If the path is not + * included with the name, the current directory is assumed.
    + */ + public String lpFile; + + /** + *

    + * Type: LPCTSTR + *

    + *

    + * Optional. The address of a null-terminated string that contains the + * application parameters. The parameters must be separated by spaces. + * If the lpFile member specifies a document file, + * lpParameters should be NULL. + *

    + */ + public String lpParameters; + + /** + *

    + * Type: LPCTSTR + *

    + *

    + * Optional. The address of a null-terminated string that specifies the + * name of the working directory. If this member is + * NULL, the current directory is used as the working + * directory. + *

    + */ + public String lpDirectory; + + /** + *

    + * Type: int + *

    + *

    + * Required. Flags that specify how an application is to be shown when + * it is opened; one of the SW_ values listed for the + * ShellExecute + * function. If lpFile specifies a document file, + * the flag is simply passed to the associated application. It is up to + * the application to decide how to handle it. + *

    + */ + public int nShow; + + /** + *

    + * Type: HINSTANCE + *

    + *

    + * [out] If SEE_MASK_NOCLOSEPROCESS is set and the call succeeds, it + * sets this member to a value greater than 32. If the function fails, + * it is set to an SE_ERR_XXX error value that indicates the cause of + * the failure. Although hInstApp is declared as an + * HINSTANCE for compatibility with 16-bit Windows applications, it is + * not a true HINSTANCE. It can be cast only to an int + * and compared to either 32 or the following SE_ERR_XXX error codes. + *

    + *
    + *
    + *

    + * SE_ERR_FNF (2) + *

    + *
    + *
    + *

    + * File not found. + *

    + *
    + *
    + *

    + * SE_ERR_PNF (3) + *

    + *
    + *
    + *

    + * Path not found. + *

    + *
    + *
    + *

    + * SE_ERR_ACCESSDENIED (5) + *

    + *
    + *
    + *

    + * Access denied. + *

    + *
    + *
    + *

    + * SE_ERR_OOM (8) + *

    + *
    + *
    + *

    + * Out of memory. + *

    + *
    + *
    + *

    + * SE_ERR_DLLNOTFOUND (32) + *

    + *
    + *
    + *

    + * Dynamic-link library not found. + *

    + *
    + *
    + *

    + * SE_ERR_SHARE (26) + *

    + *
    + *
    + *

    + * Cannot share an open file. + *

    + *
    + *
    + *

    + * SE_ERR_ASSOCINCOMPLETE (27) + *

    + *
    + *
    + *

    + * File association information not complete. + *

    + *
    + *
    + *

    + * SE_ERR_DDETIMEOUT (28) + *

    + *
    + *
    + *

    + * DDE operation timed out. + *

    + *
    + *
    + *

    + * SE_ERR_DDEFAIL (29) + *

    + *
    + *
    + *

    + * DDE operation failed. + *

    + *
    + *
    + *

    + * SE_ERR_DDEBUSY (30) + *

    + *
    + *
    + *

    + * DDE operation is busy. + *

    + *
    + *
    + *

    + * SE_ERR_NOASSOC (31) + *

    + *
    + *
    + *

    + * File association not available. + *

    + *
    + *
    + */ + public HINSTANCE hInstApp; + + /** + *

    + * Type: LPVOID + *

    + *

    + * The address of an absolute + * ITEMIDLIST + * structure (PCIDLIST_ABSOLUTE) to contain an item identifier list that + * uniquely identifies the file to execute. This member is ignored if + * the fMask member does not include + * SEE_MASK_IDLIST or + * SEE_MASK_INVOKEIDLIST. + *

    + */ + public Pointer lpIDList; + + /** + *

    + * Type: LPCTSTR + *

    + * + *

    + * The address of a null-terminated string that specifies one of the + * following: + *

    + *
      + *
    • A ProgId. For example, "Paint.Picture".
    • + *
    • A URI protocol scheme. For example, "http".
    • + *
    • A file extension. For example, ".txt".
    • + *
    • A registry path under HKEY_CLASSES_ROOT that names a subkey that + * contains one or more Shell verbs. This key will have a subkey that + * conforms to the Shell verb registry schema, such as + *

      + * shell\verb name + *

      + * .
    • + *
    + *

    + * This member is ignored if fMask does not include + * SEE_MASK_CLASSNAME. + *

    + */ + public String lpClass; + + /** + *

    + * Type: HKEY + *

    + *

    + * A handle to the registry key for the file type. The access rights for + * this registry key should be set to KEY_READ. This member is ignored + * if fMask does not include + * SEE_MASK_CLASSKEY. + *

    + */ + public HKEY hKeyClass; + + /** + *

    + * Type: DWORD + *

    + *

    + * A keyboard shortcut to associate with the application. The low-order + * word is the virtual key code, and the high-order word is a modifier + * flag (HOTKEYF_). For a list of modifier flags, see the description of + * the + * WM_SETHOTKEY + * message. This member is ignored if fMask does + * not include SEE_MASK_HOTKEY. + *

    + */ + public int dwHotKey; + + /** + * This is actually a union: + * + *
    +		 * union { HANDLE hIcon; HANDLE hMonitor; } DUMMYUNIONNAME;
    +		 * 
    + * + * DUMMYUNIONNAME + *
    + *
    hIcon
    + *
    + *

    + * Type: HANDLE + *

    + *
    + *
    + *

    + * A handle to the icon for the file type. This member is ignored if + * fMask does not include + * SEE_MASK_ICON. This value is used only in + * Windows XP and earlier. It is ignored as of Windows Vista. + *

    + *
    + *
    hMonitor
    + *
    + *

    + * Type: HANDLE + *

    + *
    + *
    + *

    + * A handle to the monitor upon which the document is to be displayed. + * This member is ignored if fMask does not include + * SEE_MASK_HMONITOR. + *

    + *
    + *
    + */ + public HANDLE hMonitor; + + /** + *

    + * Type: HANDLE + *

    + *

    + * A handle to the newly started application. This member is set on + * return and is always NULL unless + * fMask is set to + * SEE_MASK_NOCLOSEPROCESS. Even if + * fMask is set to + * SEE_MASK_NOCLOSEPROCESS, hProcess + * will be NULL if no process was launched. For + * example, if a document to be launched is a URL and an instance of + * Internet Explorer is already running, it will display the document. + * No new process is launched, and hProcess will be + * NULL. + *

    + *
    Note   + * ShellExecuteEx + * does not always return an hProcess, even if a + * process is launched as the result of the call. For example, an + * hProcess does not return when you use + * SEE_MASK_INVOKEIDLIST to invoke + * IContextMenu + * .
    + */ + public HANDLE hProcess; + + @Override + protected List getFieldOrder() { + return FIELDS; + } + } + } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/ShlObj.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/ShlObj.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/ShlObj.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/ShlObj.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2010 Daniel Doubrovkine, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Shlwapi.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Shlwapi.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Shlwapi.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Shlwapi.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,69 @@ +/* + * 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; + +/* + * @author L W Ahonen, lwahonen@iki.fi + */ + +import com.sun.jna.Native; +import com.sun.jna.Pointer; +import com.sun.jna.ptr.PointerByReference; +import com.sun.jna.win32.StdCallLibrary; +import com.sun.jna.win32.W32APIOptions; +import com.sun.jna.platform.win32.WinNT.*; + +public interface Shlwapi extends StdCallLibrary { + Shlwapi INSTANCE = Native.loadLibrary("Shlwapi", Shlwapi.class, W32APIOptions.DEFAULT_OPTIONS); + + /** + * Takes an STRRET structure returned by IShellFolder::GetDisplayNameOf and returns a pointer + * to an allocated string containing the display name. + * + * @param pstr + * A pointer to the STRRET structure. When the function returns, + * this pointer will no longer be valid. + * @param pidl + * A pointer to the item's ITEMIDLIST structure. This value can be NULL. + * + * @param ppszName + * A pointer to an allocated string containing the result. StrRetToStr allocates + * memory for this string with CoTaskMemAlloc. You should free the string + * with CoTaskMemFree when it is no longer needed. + * + * @return If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. + */ + + HRESULT StrRetToStr(PointerByReference pstr, Pointer pidl, PointerByReference ppszName); + + /** + * Determines if a path string is a valid Universal Naming Convention (UNC) path, as opposed to + * a path based on a drive letter. + * + * @param path + * A string containing the path to validate. + * + * @return TRUE if the string is a valid UNC path; otherwise, FALSE. + */ + boolean PathIsUNC(String path); +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Sspi.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Sspi.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Sspi.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Sspi.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,32 +1,41 @@ /* 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * You can freely decide which license you want to apply to + * the project. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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 java.util.Arrays; import java.util.List; import com.sun.jna.Memory; import com.sun.jna.Pointer; import com.sun.jna.Structure; -import com.sun.jna.WString; -import com.sun.jna.win32.StdCallLibrary; +import com.sun.jna.win32.W32APITypeMapper; /** * Ported from Sspi.h. * Microsoft Windows SDK 6.0A. * @author dblock[at]dblock.org */ -public interface Sspi extends StdCallLibrary { +public interface Sspi { /** * Maximum size in bytes of a security token. @@ -36,9 +45,9 @@ // Flags for the fCredentialUse parameter of AcquireCredentialsHandle /** - * Validate an incoming server credential. Inbound credentials might be validated + * Validate an incoming server credential. Inbound credentials might be validated * by using an authenticating authority when InitializeSecurityContext or - * AcceptSecurityContext is called. If such an authority is not available, the function will + * AcceptSecurityContext is called. If such an authority is not available, the function will * fail and return SEC_E_NO_AUTHENTICATING_AUTHORITY. Validation is package specific. */ int SECPKG_CRED_INBOUND = 1; @@ -48,11 +57,11 @@ */ int SECPKG_CRED_OUTBOUND = 2; - + // Flags for the TargetDataRep parameter of AcceptSecurityContext and InitializeSecurityContext /** - * Specifies Native data representation. + * Specifies Native data representation. */ int SECURITY_NATIVE_DREP = 0x10; @@ -60,7 +69,7 @@ // Flags for the fContextReq parameter of InitializeSecurityContext or AcceptSecurityContext. /** - * The security package allocates output buffers for you. + * The security package allocates output buffers for you. * When you have finished using the output buffers, free them by calling the FreeContextBuffer function. */ int ISC_REQ_ALLOCATE_MEMORY = 0x00000100; @@ -76,8 +85,8 @@ int ISC_REQ_CONNECTION = 0x00000800; /** - * The server can use the context to authenticate to other servers as the client. - * The ISC_REQ_MUTUAL_AUTH flag must be set for this flag to work. Valid for Kerberos. + * The server can use the context to authenticate to other servers as the client. + * The ISC_REQ_MUTUAL_AUTH flag must be set for this flag to work. Valid for Kerberos. * Ignore this flag for constrained delegation. */ int ISC_REQ_DELEGATE = 0x00000001; @@ -98,7 +107,7 @@ int ISC_REQ_MUTUAL_AUTH = 0x00000002; /** - * Detect replayed messages that have been encoded by using the + * Detect replayed messages that have been encoded by using the * EncryptMessage or MakeSignature functions. */ int ISC_REQ_REPLAY_DETECT = 0x00000004; @@ -128,31 +137,141 @@ */ int SECBUFFER_DATA = 1; /** - * This buffer type is used to indicate the security token portion of the message. + * This buffer type is used to indicate the security token portion of the message. * This is read-only for input parameters or read/write for output parameters. */ int SECBUFFER_TOKEN = 2; - + + // for ulAttribute parameter in QueryContextAttributes function + // (https://msdn.microsoft.com/en-us/library/windows/desktop/aa379326(v=vs.85).aspx) + /** + * The pBuffer parameter contains a pointer to a + * {@link SecPkgContext_PackageInfo} structure. + * + * Returns information on the SSP in use. + */ + int SECPKG_ATTR_PACKAGE_INFO = 0x0000000A; + + // flags for SecPkgInfo fCapabilities + // (https://msdn.microsoft.com/en-us/library/windows/desktop/aa380104(v=vs.85).aspx) + /** + * Supports integrity on messages + */ + int SECPKG_FLAG_INTEGRITY = 0x00000001; + /** + * Supports privacy (confidentiality) + */ + int SECPKG_FLAG_PRIVACY = 0x00000002; + /** + * Only security token needed + */ + int SECPKG_FLAG_TOKEN_ONLY = 0x00000004; + /** + * Datagram RPC support + */ + int SECPKG_FLAG_DATAGRAM = 0x00000008; + /** + * Connection oriented RPC support + */ + int SECPKG_FLAG_CONNECTION = 0x00000010; + /** + * Full 3-leg required for re-auth. + */ + int SECPKG_FLAG_MULTI_REQUIRED = 0x00000020; + /** + * Server side functionality not available + */ + int SECPKG_FLAG_CLIENT_ONLY = 0x00000040; + /** + * Supports extended error msgs + */ + int SECPKG_FLAG_EXTENDED_ERROR = 0x00000080; + /** + * Supports impersonation + */ + int SECPKG_FLAG_IMPERSONATION = 0x00000100; + /** + * Accepts Win32 names + */ + int SECPKG_FLAG_ACCEPT_WIN32_NAME = 0x00000200; + /** + * Supports stream semantics + */ + int SECPKG_FLAG_STREAM = 0x00000400; + /** + * Can be used by the negotiate package + */ + int SECPKG_FLAG_NEGOTIABLE = 0x00000800; + /** + * GSS Compatibility Available + */ + int SECPKG_FLAG_GSS_COMPATIBLE = 0x00001000; + /** + * Supports common LsaLogonUser + */ + int SECPKG_FLAG_LOGON = 0x00002000; + /** + * Token Buffers are in ASCII + */ + int SECPKG_FLAG_ASCII_BUFFERS = 0x00004000; + /** + * Package can fragment to fit + */ + int SECPKG_FLAG_FRAGMENT = 0x00008000; + /** + * Package can perform mutual authentication + */ + int SECPKG_FLAG_MUTUAL_AUTH = 0x00010000; + /** + * Package can delegate + */ + int SECPKG_FLAG_DELEGATION = 0x00020000; + /** + * Supports callers with restricted tokens. + */ + int SECPKG_FLAG_RESTRICTED_TOKENS = 0x80000; + /** + * The security package extends the Microsoft Negotiate security package. + */ + int SECPKG_FLAG_NEGO_EXTENDER = 0x00100000; + /** + * This package is negotiated by the package of type SECPKG_FLAG_NEGO_EXTENDER. + */ + int SECPKG_FLAG_NEGOTIABLE2 = 0x00200000; + /** + * This package receives all calls from app container apps. + */ + int SECPKG_FLAG_APPCONTAINER_PASSTHROUGH = 0x00400000; + /** + * This package receives calls from app container apps if one of the following checks succeeds. + *
      + *
    • Caller has default credentials capability.
    • + *
    • The target is a proxy server.
    • + *
    • The caller has supplied credentials.
    • + *
    + */ + int SECPKG_FLAG_APPCONTAINER_CHECKS = 0x00800000; + /** * Security handle. */ - public static class SecHandle extends Structure { - public Pointer dwLower; - public Pointer dwUpper; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "dwLower", "dwUpper" }); - } + public static class SecHandle extends Structure { public static class ByReference extends SecHandle implements Structure.ByReference { } - + + public static final List FIELDS = createFieldsOrder("dwLower", "dwUpper"); + + public Pointer dwLower; + public Pointer dwUpper; + /** * An empty SecHandle. */ public SecHandle() { + super(); } - + /** * Returns true if the handle is NULL. * @return @@ -161,6 +280,11 @@ public boolean isNull() { return dwLower == null && dwUpper == null; } + + @Override + protected List getFieldOrder() { + return FIELDS; + } } /** @@ -170,43 +294,46 @@ public static class ByReference extends PSecHandle implements Structure.ByReference { } - + + public static final List FIELDS = createFieldsOrder("secHandle"); /** * The first entry in an array of SecPkgInfo structures. */ public SecHandle.ByReference secHandle; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "secHandle" }); - } - + public PSecHandle() { + super(); } public PSecHandle(SecHandle h) { super(h.getPointer()); read(); } + + @Override + protected List getFieldOrder() { + return FIELDS; + } } - + /** * Credentials handle. */ - public static class CredHandle extends SecHandle { + public static class CredHandle extends SecHandle { } - + /** * Security context handle. */ - public static class CtxtHandle extends SecHandle { + public static class CtxtHandle extends SecHandle { } /** - * The SecBuffer structure describes a buffer allocated by a transport application + * The SecBuffer structure describes a buffer allocated by a transport application * to pass to a security package. */ public static class SecBuffer extends Structure { - + /** * A ByReference SecBuffer. */ @@ -216,7 +343,7 @@ */ public ByReference() { } - + /** * Create a SecBuffer of a given type and size. * @param type @@ -232,13 +359,14 @@ super(type, token); } } - + + public static final List FIELDS = createFieldsOrder("cbBuffer", "BufferType", "pvBuffer"); /** * Specifies the size, in bytes, of the buffer pointed to by the pvBuffer member. */ public int cbBuffer; /** - * Bit flags that indicate the type of buffer. Must be one of the values of + * Bit flags that indicate the type of buffer. Must be one of the values of * the SecBufferType enumeration. */ public int BufferType = SECBUFFER_EMPTY; @@ -246,17 +374,14 @@ * A pointer to a buffer. */ public Pointer pvBuffer; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "cbBuffer", "BufferType", "pvBuffer" }); - } - + /** * Create a new SECBUFFER_EMPTY buffer. */ public SecBuffer() { + super(); } - + /** * Create a SecBuffer of a given type and size. * @param type @@ -265,11 +390,11 @@ * Buffer size, eg. MAX_TOKEN_SIZE. */ public SecBuffer(int type, int size) { - cbBuffer = size; + cbBuffer = size; pvBuffer = new Memory(size); BufferType = type; } - + /** * Create a SecBuffer of a given type with initial data. * @param type @@ -278,12 +403,12 @@ * Existing token. */ public SecBuffer(int type, byte[] token) { - cbBuffer = token.length; + cbBuffer = token.length; pvBuffer = new Memory(token.length); pvBuffer.write(0, token, 0, token.length); BufferType = type; } - + /** * Get buffer bytes. * @return @@ -292,10 +417,15 @@ public byte[] getBytes() { return pvBuffer == null ? null : pvBuffer.getByteArray(0, cbBuffer); } + + @Override + protected List getFieldOrder() { + return FIELDS; + } } public static class SecBufferDesc extends Structure { - + public static final List FIELDS = createFieldsOrder("ulVersion", "cBuffers", "pBuffers"); /** * Version number. */ @@ -311,27 +441,22 @@ new SecBuffer.ByReference() }; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "ulVersion", "cBuffers", "pBuffers" }); - } - /** * Create a new SecBufferDesc with one SECBUFFER_EMPTY buffer. */ public SecBufferDesc() { + super(); } - + /** * Create a new SecBufferDesc with initial data. - * @param type - * Token type. - * @param token - * Initial token data. + * @param type Token type. + * @param token Initial token data. */ public SecBufferDesc(int type, byte[] token) { pBuffers[0] = new SecBuffer.ByReference(type, token); } - + /** * Create a new SecBufferDesc with one SecBuffer of a given type and size. * @param type type @@ -339,37 +464,38 @@ */ public SecBufferDesc(int type, int tokenSize) { pBuffers[0] = new SecBuffer.ByReference(type, tokenSize); - } - + } + public byte[] getBytes() { return pBuffers[0].getBytes(); } + + @Override + protected List getFieldOrder() { + return FIELDS; + } } - + /** * A security integer. */ public static class SECURITY_INTEGER extends Structure { + public static final List FIELDS = createFieldsOrder("dwLower", "dwUpper"); public int dwLower; public int dwUpper; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "dwLower", "dwUpper" }); - } - /** - * An security integer of 0. - */ - public SECURITY_INTEGER() { + @Override + protected List getFieldOrder() { + return FIELDS; } } - + /** * A timestamp. */ public static class TimeStamp extends SECURITY_INTEGER { } - + /** * A pointer to an array of SecPkgInfo structures. */ @@ -378,29 +504,34 @@ public static class ByReference extends PSecPkgInfo implements Structure.ByReference { } - + + public static final List FIELDS = createFieldsOrder("pPkgInfo"); + /** * The first entry in an array of SecPkgInfo structures. */ public SecPkgInfo.ByReference pPkgInfo; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "pPkgInfo" }); - } - + public PSecPkgInfo() { + super(); + } + + @Override + protected List getFieldOrder() { + return FIELDS; } - + /** * An array of SecPkgInfo structures. */ + @Override public SecPkgInfo.ByReference[] toArray(int size) { return (SecPkgInfo.ByReference[]) pPkgInfo.toArray(size); } } - + /** - * The SecPkgInfo structure provides general information about a security package, + * The SecPkgInfo structure provides general information about a security package, * such as its name and capabilities. */ public static class SecPkgInfo extends Structure { @@ -408,44 +539,75 @@ /** * A reference pointer to a SecPkgInfo structure. */ - public static class ByReference extends SecPkgInfo implements Structure.ByReference { + public static class ByReference extends SecPkgInfo implements Structure.ByReference { } - + + public static final List FIELDS = createFieldsOrder( + "fCapabilities", "wVersion", "wRPCID", "cbMaxToken", "Name", "Comment"); + /** * Set of bit flags that describes the capabilities of the security package. */ - public int fCapabilities; + public int fCapabilities; /** - * Specifies the version of the package protocol. Must be 1. + * Specifies the version of the package protocol. Must be 1. */ public short wVersion = 1; /** - * Specifies a DCE RPC identifier, if appropriate. If the package does not implement one of - * the DCE registered security systems, the reserved value SECPKG_ID_NONE is used. + * Specifies a DCE RPC identifier, if appropriate. If the package does not implement one of + * the DCE registered security systems, the reserved value SECPKG_ID_NONE is used. */ public short wRPCID; /** - * Specifies the maximum size, in bytes, of the token. + * Specifies the maximum size, in bytes, of the token. */ public int cbMaxToken; /** * Pointer to a null-terminated string that contains the name of the security package. */ - public WString Name; + public String Name; /** - * Pointer to a null-terminated string. This can be any additional string passed - * back by the package. + * Pointer to a null-terminated string. This can be any additional string passed + * back by the package. */ - public WString Comment; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "fCapabilities", "wVersion", "wRPCID", "cbMaxToken", "Name", "Comment" }); + public String Comment; + + public SecPkgInfo() { + super(W32APITypeMapper.DEFAULT); + } + + @Override + protected List getFieldOrder() { + return FIELDS; + } + } + + /** + * The SecPkgContext_PackageInfo structure. + */ + public static class SecPkgContext_PackageInfo extends Structure { + /** + * A reference pointer to a SecPkgContext_PackageInfo structure. + */ + public static class ByReference extends SecPkgContext_PackageInfo implements Structure.ByReference { } + public static final List FIELDS = createFieldsOrder("PackageInfo"); + /** - * Create a new package info. + * Pointer to a SecPkgInfo structure containing the name of the SSP in + * use. */ - public SecPkgInfo() { + public SecPkgInfo.ByReference PackageInfo; + + public SecPkgContext_PackageInfo() { + super(W32APITypeMapper.DEFAULT); + } + + @Override + protected List getFieldOrder() { + return FIELDS; } } + } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Tlhelp32.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Tlhelp32.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Tlhelp32.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Tlhelp32.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,26 +1,39 @@ -/* This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. +/* + * 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 java.util.Arrays; import java.util.List; +import com.sun.jna.Native; import com.sun.jna.Pointer; import com.sun.jna.Structure; -import com.sun.jna.win32.StdCallLibrary; +import com.sun.jna.platform.win32.WinDef.DWORD; +import com.sun.jna.platform.win32.WinDef.HMODULE; /** * Interface for the Tlhelp32.h header file. */ -public interface Tlhelp32 extends StdCallLibrary { +public interface Tlhelp32 { /** * Includes all heaps of the process specified in th32ProcessID in the snapshot. To enumerate the heaps, see @@ -39,8 +52,20 @@ WinDef.DWORD TH32CS_SNAPTHREAD = new WinDef.DWORD(0x00000004); /** - * Includes all modules of the process specified in th32ProcessID in the snapshot. To enumerate the modules, see - * Module32First. If the function fails with ERROR_BAD_LENGTH, retry the function until it succeeds. + * + * Used with Kernel32.CreateToolhelp32Snapshot
    + * Includes all modules of the process specified in th32ProcessID in the + * snapshot.
    + * To enumerate the modules, see Module32First.
    + * If the function fails with ERROR_BAD_LENGTH, retry the function until it + * succeeds.
    + * 64-bit Windows: Using this flag in a 32-bit process includes the 32-bit + * modules of the process specified in th32ProcessID, while using it in a + * 64-bit process includes the 64-bit modules.
    + * To include the 32-bit modules of the process specified in th32ProcessID + * from a 64-bit process, use the TH32CS_SNAPMODULE32 flag. + * + * @see MSDN */ WinDef.DWORD TH32CS_SNAPMODULE = new WinDef.DWORD(0x00000008); @@ -62,6 +87,8 @@ */ WinDef.DWORD TH32CS_INHERIT = new WinDef.DWORD(0x80000000); + int MAX_MODULE_NAME32 = 255; + /** * Describes an entry from a list of the processes residing in the system address space when a snapshot was taken. */ @@ -76,14 +103,9 @@ } } - public PROCESSENTRY32() { - dwSize = new WinDef.DWORD(size()); - } - - public PROCESSENTRY32(Pointer memory) { - super(memory); - read(); - } + public static final List FIELDS = createFieldsOrder( + "dwSize", "cntUsage", "th32ProcessID", "th32DefaultHeapID", "th32ModuleID", + "cntThreads", "th32ParentProcessID", "pcPriClassBase", "dwFlags", "szExeFile"); /** * The size of the structure, in bytes. Before calling the Process32First function, set this member to @@ -138,9 +160,126 @@ * retrieve the full path of the executable file for a 64-bit process. */ public char[] szExeFile = new char[WinDef.MAX_PATH]; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "dwSize", "cntUsage", "th32ProcessID", "th32DefaultHeapID", "th32ModuleID", "cntThreads", "th32ParentProcessID", "pcPriClassBase", "dwFlags", "szExeFile" }); + + public PROCESSENTRY32() { + dwSize = new WinDef.DWORD(size()); + } + + public PROCESSENTRY32(Pointer memory) { + super(memory); + read(); + } + + @Override + protected List getFieldOrder() { + return FIELDS; + } + } + + /** + * Describes an entry from a list of the modules belonging to the specified + * process. + * + * @see MSDN + */ + public class MODULEENTRY32W extends Structure { + + /** + * A representation of a MODULEENTRY32 structure as a reference + */ + public static class ByReference extends MODULEENTRY32W implements Structure.ByReference { + public ByReference() { + } + + public ByReference(Pointer memory) { + super(memory); + } + } + + public static final List FIELDS = createFieldsOrder( + "dwSize", "th32ModuleID", "th32ProcessID", "GlblcntUsage", + "ProccntUsage", "modBaseAddr", "modBaseSize", "hModule", "szModule", "szExePath"); + + /** + * The size of the structure, in bytes. Before calling the Module32First + * function, set this member to sizeof(MODULEENTRY32). If you do not + * initialize dwSize, Module32First fails. + */ + public DWORD dwSize; + + /** + * This member is no longer used, and is always set to one. + */ + public DWORD th32ModuleID; + + /** + * The identifier of the process whose modules are to be examined. + */ + public DWORD th32ProcessID; + + /** + * The load count of the module, which is not generally meaningful, and + * usually equal to 0xFFFF. + */ + public DWORD GlblcntUsage; + + /** + * The load count of the module (same as GlblcntUsage), which is not + * generally meaningful, and usually equal to 0xFFFF. + */ + public DWORD ProccntUsage; + + /** + * The base address of the module in the context of the owning process. + */ + public Pointer modBaseAddr; + + /** + * The size of the module, in bytes. + */ + public DWORD modBaseSize; + + /** + * A handle to the module in the context of the owning process. + */ + public HMODULE hModule; + + /** + * The module name. + */ + public char[] szModule = new char[MAX_MODULE_NAME32 + 1]; + + /** + * The module path. + */ + public char[] szExePath = new char[Kernel32.MAX_PATH]; + + public MODULEENTRY32W() { + dwSize = new WinDef.DWORD(size()); + } + + public MODULEENTRY32W(Pointer memory) { + super(memory); + read(); + } + + /** + * @return The module name. + */ + public String szModule() { + return Native.toString(this.szModule); + } + + /** + * @return The module path. + */ + public String szExePath() { + return Native.toString(this.szExePath); + } + + @Override + protected List getFieldOrder() { + return FIELDS; } } } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/User32.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/User32.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/User32.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/User32.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,21 +1,31 @@ /* Copyright (c) 2007, 2013 Timothy Wall, Markus Karg, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

    - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.Native; import com.sun.jna.Pointer; import com.sun.jna.Structure; -import com.sun.jna.WString; import com.sun.jna.platform.win32.WinGDI.ICONINFO; import com.sun.jna.ptr.ByteByReference; import com.sun.jna.ptr.IntByReference; @@ -35,13 +45,12 @@ public interface User32 extends StdCallLibrary, WinUser, WinNT { /** The instance. */ - User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class, - W32APIOptions.DEFAULT_OPTIONS); + User32 INSTANCE = Native.loadLibrary("user32", User32.class, W32APIOptions.DEFAULT_OPTIONS); /** * Handle for message-only window. */ - public static final HWND HWND_MESSAGE = new HWND(Pointer.createConstant(-3)); + HWND HWND_MESSAGE = new HWND(Pointer.createConstant(-3)); /** The cs globalclass. */ int CS_GLOBALCLASS = 0x4000; @@ -59,6 +68,19 @@ int DEVICE_NOTIFY_ALL_INTERFACE_CLASSES = 0x00000004; /** + *

    + * Sets the show state based on the SW_ value specified in the + * STARTUPINFO + * structure passed to the + * CreateProcess + * function by the program that started the application. + *

    + */ + int SW_SHOWDEFAULT = 10; + + /** * This function retrieves a handle to a display device context (DC) for the * client area of the specified window. The display device context can be * used in subsequent graphics display interface (GDI) functions to draw in @@ -177,12 +199,31 @@ * Long pointer to a RECT structure that receives the screen * coordinates of the upper-left and lower-right corners of the * window. - * @return Nonzero indicates success. Zero indicates failure. To get - * extended error information, call GetLastError. + * @return If the function succeeds, the return value is nonzero. If the + * function fails, the return value is zero. */ boolean GetWindowRect(HWND hWnd, RECT rect); /** + * This function retrieves the coordinates of a window's client area. + * The client coordinates specify the upper-left and lower-right corners of the + * client area. Because client coordinates are relative to the upper-left + * corner of a window's client area, the coordinates of the upper-left corner + * are (0,0). + * + * @param hWnd + * Handle to the window. + * @param rect + * Long pointer to a RECT structure that structure that receives + * the client coordinates. The left and top members are zero. The + * right and bottom members contain the width and height of the + * window. + * @return If the function succeeds, the return value is nonzero. If the + * function fails, the return value is zero. + */ + boolean GetClientRect(HWND hWnd, RECT rect); + + /** * This function copies the text of the specified window's title bar - if it * has one - into a buffer. If the specified window is a control, the text * of the control is copied. @@ -234,8 +275,7 @@ * @return The return value is the total number of TCHARs copied into the * buffer. */ - int GetWindowModuleFileName(HWND hWnd, char[] lpszFileName, - int cchFileNameMax); + int GetWindowModuleFileName(HWND hWnd, char[] lpszFileName, int cchFileNameMax); /** * This function retrieves the identifier of the thread that created the @@ -316,8 +356,7 @@ * there are no windows found in the thread specified by dwThreadId, * the return value is FALSE. */ - boolean EnumThreadWindows(int dwThreadId, WNDENUMPROC lpEnumFunc, - Pointer data); + boolean EnumThreadWindows(int dwThreadId, WNDENUMPROC lpEnumFunc, Pointer data); /** * The FlashWindowEx function flashes the specified window. It does not @@ -333,27 +372,27 @@ boolean FlashWindowEx(FLASHWINFO pfwi); /** - * This function loads the specified icon resource from the executable - * (.exe) file associated with an application instance. - * - * @param hInstance - * Handle to an instance of the module whose executable file - * contains the icon to be loaded. This parameter must be NULL - * when a standard icon is being loaded. - * @param iconName - * Long pointer to a null-terminated string that contains the - * name of the icon resource to be loaded. Alternatively, this - * parameter can contain the resource identifier in the low-order - * word and zero in the high-order word. Use the MAKEINTRESOURCE - * macro to create this value. - *

    - * To use one of the predefined icons, set the hInstance - * parameter to NULL and the lpIconName parameter to one of the - * following values: {@link WinUser#IDC_APPSTARTING} etc.

    - * @return A handle to the newly loaded icon indicates success. NULL - * indicates failure. To get extended error information, call - * GetLastError. - */ + * This function loads the specified icon resource from the executable + * (.exe) file associated with an application instance. + * + * @param hInstance + * Handle to an instance of the module whose executable file + * contains the icon to be loaded. This parameter must be NULL + * when a standard icon is being loaded. + * @param iconName + * Long pointer to a null-terminated string that contains the + * name of the icon resource to be loaded. Alternatively, this + * parameter can contain the resource identifier in the low-order + * word and zero in the high-order word. Use the MAKEINTRESOURCE + * macro to create this value. + *

    + * To use one of the predefined icons, set the hInstance + * parameter to NULL and the lpIconName parameter to one of the + * following values: {@link WinUser#IDC_APPSTARTING} etc.

    + * @return A handle to the newly loaded icon indicates success. NULL + * indicates failure. To get extended error information, call + * GetLastError. + */ HICON LoadIcon(HINSTANCE hInstance, String iconName); /** @@ -492,8 +531,7 @@ * function fails, the return value is zero. To get extended error * information, call GetLastError. */ - boolean SetLayeredWindowAttributes(HWND hwnd, int crKey, byte bAlpha, - int dwFlags); + boolean SetLayeredWindowAttributes(HWND hwnd, int crKey, byte bAlpha, int dwFlags); /** * The GetLayeredWindowAttributes function retrieves the opacity and @@ -525,7 +563,7 @@ * information, call GetLastError. */ boolean GetLayeredWindowAttributes(HWND hwnd, IntByReference pcrKey, - ByteByReference pbAlpha, IntByReference pdwFlags); + ByteByReference pbAlpha, IntByReference pdwFlags); /** * The UpdateLayeredWindow function updates the position, size, shape, @@ -646,8 +684,7 @@ * hook procedure. If the function fails, the return value is NULL. * To get extended error information, call GetLastError. */ - HHOOK SetWindowsHookEx(int idHook, HOOKPROC lpfn, HINSTANCE hMod, - int dwThreadId); + HHOOK SetWindowsHookEx(int idHook, HOOKPROC lpfn, HINSTANCE hMod, int dwThreadId); /** * The CallNextHookEx function passes the hook information to the next hook @@ -703,10 +740,14 @@ * @param wMsgFilterMax * Specifies the integer value of the highest message value to be * retrieved. - * @return Nonzero indicates that the function retrieves a message other - * than WM_QUIT. Zero indicates that the function retrieves the - * WM_QUIT message, or that lpMsg is an invalid pointer. To get - * extended error information, call GetLastError. + * @return If the function retrieves a message other than WM_QUIT, the + * return value is nonzero. + * + *

    If the function retrieves the WM_QUIT message, the return value is zero.

    + * + *

    If there is an error, the return value is -1. For example, the function + * fails if hWnd is an invalid window handle or lpMsg is an invalid pointer. + * To get extended error information, call GetLastError.

    */ int GetMessage(MSG lpMsg, HWND hWnd, int wMsgFilterMin, int wMsgFilterMax); @@ -730,7 +771,7 @@ * @return Nonzero indicates success. Zero indicates failure. */ boolean PeekMessage(MSG lpMsg, HWND hWnd, int wMsgFilterMin, - int wMsgFilterMax, int wRemoveMsg); + int wMsgFilterMax, int wRemoveMsg); /** * This function translates virtual-key messages into character messages. @@ -782,6 +823,46 @@ void PostMessage(HWND hWnd, int msg, WPARAM wParam, LPARAM lParam); /** + * Posts a message to the message queue of the specified thread. It returns + * without waiting for the thread to process the message. + * + * @param idThread The identifier of the thread to which the message is to + * be posted. + * + *

    The function fails if the specified thread does not have a + * message queue. The system creates a thread's message queue when the + * thread makes its first call to one of the User or GDI functions.

    + * + *

    Message posting is subject to UIPI. The thread of a process can post + * messages only to posted-message queues of threads in processes of lesser + * or equal integrity level.

    + * + *

    This thread must have the SE_TCB_NAME privilege to post a message to a + * thread that belongs to a process with the same locally unique identifier + * (LUID) but is in a different desktop. Otherwise, the function fails + * and returns ERROR_INVALID_THREAD_ID.

    + * + *

    This thread must either belong to the same desktop as the calling + * thread or to a process with the same LUID. Otherwise, the function + * fails and returns ERROR_INVALID_THREAD_ID.

    + * + * @param Msg The type of message to be posted. + * + * @param wParam Additional message-specific information. + * + * @param lParam Additional message-specific information. + * + * @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.

    GetLastError returns + * ERROR_INVALID_THREAD_ID if idThread is not a valid thread identifier, or + * if the thread specified by idThread does not have a message queue.

    + *

    GetLastError returns ERROR_NOT_ENOUGH_QUOTA when the message limit is hit.

    + */ + int PostThreadMessage(int idThread, int Msg, WPARAM wParam, LPARAM lParam); + + /** * This function indicates to Windows that a thread has made a request to * terminate (quit). It is typically used in response to a WM_DESTROY * message. @@ -809,7 +890,7 @@ * the return value is zero. GetLastError does not provide extended * error information. */ - public int GetSystemMetrics(int nIndex); + int GetSystemMetrics(int nIndex); /** * Changes the parent window of the specified child window. @@ -880,8 +961,7 @@ * If the function fails, the return value is zero. To get extended * error information, call GetLastError. */ - boolean MoveWindow(HWND hWnd, int X, int Y, int nWidth, int nHeight, - boolean bRepaint); + boolean MoveWindow(HWND hWnd, int X, int Y, int nWidth, int nHeight, boolean bRepaint); /** * Changes the size, position, and Z order of a child, pop-up, or top-level @@ -1108,8 +1188,7 @@ * @return If the function succeeds, the return value is nonzero. If the * function fails, the return value is zero. */ - boolean RedrawWindow(HWND hWnd, RECT lprcUpdate, - HRGN hrgnUpdate, DWORD flags); + boolean RedrawWindow(HWND hWnd, RECT lprcUpdate, HRGN hrgnUpdate, DWORD flags); /** * Retrieves a handle to a window that has the specified relationship @@ -1263,7 +1342,7 @@ * If the function fails, the return value is zero. To get extended * error information, call {@link Kernel32#GetLastError}. */ - public ATOM RegisterClassEx(WNDCLASSEX lpwcx); + ATOM RegisterClassEx(WNDCLASSEX lpwcx); /** * Unregisters a window class, freeing the memory required for the class. @@ -1290,7 +1369,7 @@ * If the function fails, the return value is zero. To get extended * error information, call {@link Kernel32#GetLastError}. */ - public boolean UnregisterClass(WString lpClassName, HINSTANCE hInstance); + boolean UnregisterClass(String lpClassName, HINSTANCE hInstance); /** * Creates an overlapped, pop-up, or child window with an extended window @@ -1458,7 +1537,7 @@ * WM_NCCREATE * */ - public HWND CreateWindowEx(int dwExStyle, WString lpClassName, + HWND CreateWindowEx(int dwExStyle, String lpClassName, String lpWindowName, int dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam); @@ -1487,7 +1566,7 @@ * If the function fails, the return value is zero. To get extended * error information, call {@link Kernel32#GetLastError}. */ - public boolean DestroyWindow(HWND hWnd); + boolean DestroyWindow(HWND hWnd); /** * Retrieves information about a window class, including a handle to the @@ -1524,8 +1603,7 @@ * If the function fails, the return value is zero. To get extended * error information, call {@link Kernel32#GetLastError} . */ - public boolean GetClassInfoEx(HINSTANCE hinst, WString lpszClass, - WNDCLASSEX lpwcx); + boolean GetClassInfoEx(HINSTANCE hinst, String lpszClass, WNDCLASSEX lpwcx); /** * Calls the default window procedure to provide default processing for any @@ -1561,8 +1639,7 @@ * If the function fails, the return value is zero. To get extended * error information, call {@link Kernel32#GetLastError}. */ - public LRESULT DefWindowProc(HWND hWnd, int Msg, WPARAM wParam, - LPARAM lParam); + LRESULT DefWindowProc(HWND hWnd, int Msg, WPARAM wParam, LPARAM lParam); /** * Registers the device or type of device for which a window will receive @@ -1610,8 +1687,7 @@ * If the function fails, the return value is NULL. To get extended * error information, call GetLastError. */ - HDEVNOTIFY RegisterDeviceNotification(HANDLE hRecipient, - Structure notificationFilter, int Flags); + HDEVNOTIFY RegisterDeviceNotification(HANDLE hRecipient, Structure notificationFilter, int Flags); /** * Closes the specified device notification handle. @@ -1894,121 +1970,479 @@ */ BOOL LockWorkStation(); - /** - * Retrieves information about the specified icon or cursor. - * - * @param hIcon - * A handle to the icon or cursor. - *

    - * To retrieve information about a standard icon or cursor, - * specify one of the following values and use the - * MAKEINTRESOURCE macro to create this value: - * {@link WinUser#IDC_APPSTARTING} etc.

    - * @param piconinfo - * A pointer to an ICONINFO structure. The function fills in the - * structure's members. - * @return If the function succeeds, the return value is {@code true} and - * the function fills in the members of the specified ICONINFO - * structure. - *

    - * If the function fails, the return value is zero. To get extended - * error information, call {@link Kernel32#GetLastError()}.

    - */ - boolean GetIconInfo(HICON hIcon, ICONINFO piconinfo); - - /** - * Sends the specified message to one or more windows. - * - * @param hWnd - * A handle to the window whose window procedure will receive the - * message. - *

    - * If this parameter is HWND_BROADCAST ((HWND)0xffff), the - * message is sent to all top-level windows in the system, - * including disabled or invisible unowned windows. The function - * does not return until each window has timed out. Therefore, - * the total wait time can be up to the value of uTimeout - * multiplied by the number of top-level windows.

    - * @param msg - * The message to be sent. - * @param wParam - * Any additional message-specific information. - * @param lParam - * Any additional message-specific information. - * @param fuFlags - * The behavior of this function. This parameter can be one or - * more of the following values: {@link WinUser#SMTO_ABORTIFHUNG} - * etc. - * @param uTimeout - * The duration of the time-out period, in milliseconds. If the - * message is a broadcast message, each window can use the full - * time-out period. For example, if you specify a five second - * time-out period and there are three top-level windows that - * fail to process the message, you could have up to a 15 second - * delay. - * @param lpdwResult - * The result of the message processing. The value of this - * parameter depends on the message that is specified. - * @return If the function succeeds, the return value is nonzero. - * SendMessageTimeout does not provide information about individual - * windows timing out if HWND_BROADCAST is used. - *

    - * If the function fails or times out, the return value is 0. To get - * extended error information, call GetLastError. If GetLastError - * returns ERROR_TIMEOUT, then the function timed out. - *

    - * Windows 2000: If {@link Kernel32#GetLastError()} returns 0, then - * the function timed out. - */ - long SendMessageTimeout(HWND hWnd, int msg, long wParam, long lParam, - int fuFlags, int uTimeout, DWORDByReference lpdwResult); - - /** - * Retrieves the specified value from the WNDCLASSEX structure associated - * with the specified window. - * - * @param hWnd - * A handle to the window and, indirectly, the class to which the - * window belongs. - * @param nIndex - * The value to be retrieved. To retrieve a value from the extra - * class memory, specify the positive, zero-based byte offset of - * the value to be retrieved. Valid values are in the range zero - * through the number of bytes of extra class memory, minus - * eight; for example, if you specified 24 or more bytes of extra - * class memory, a value of 16 would be an index to the third - * integer.To retrieve any other value from the WNDCLASSEX - * structure, specify one of the following values: - * {@link WinUser#GCW_ATOM} etc. - * @return If the function succeeds, the return value is the requested - * value. - *

    - * If the function fails, the return value is zero. To get extended - * error information, call {@link Kernel32#GetLastError()}.

    - */ - long GetClassLongPtr(HWND hWnd, int nIndex); - - /** - * @param pRawInputDeviceList - * An array of {@link WinUser.RAWINPUTDEVICELIST} structures for the devices - * attached to the system. If (@code null}, the number of devices is - * returned in puiNumDevices - * @param puiNumDevices - * If pRawInputDeviceList is {@code null}, the function populates - * this variable with the number of devices attached to the system; - * otherwise, this variable specifies the number of {@link WinUser.RAWINPUTDEVICELIST} - * structures that can be contained in the buffer to which pRawInputDeviceList - * points. If this value is less than the number of devices attached to - * the system, the function returns the actual number of devices in this - * variable and fails with ERROR_INSUFFICIENT_BUFFER. - * @param cbSize - * The size of a {@link WinUser.RAWINPUTDEVICELIST} structure, in bytes. - * @return If the function is successful, the return value is the number of devices - * stored in the buffer pointed to by pRawInputDeviceList. On - * any other error, the function returns -1 and {@code GetLastError} - * returns the error indication. - * @see WinUser.RAWINPUTDEVICELIST#sizeof() - * @see GetRawInputDeviceList - */ - int GetRawInputDeviceList(RAWINPUTDEVICELIST[] pRawInputDeviceList, IntByReference puiNumDevices, int cbSize); + /** + * Retrieves information about the specified icon or cursor. + * + * @param hIcon + * A handle to the icon or cursor. + *

    + * To retrieve information about a standard icon or cursor, + * specify one of the following values and use the + * MAKEINTRESOURCE macro to create this value: + * {@link WinUser#IDC_APPSTARTING} etc.

    + * @param piconinfo + * A pointer to an ICONINFO structure. The function fills in the + * structure's members. + * @return If the function succeeds, the return value is {@code true} and + * the function fills in the members of the specified ICONINFO + * structure. + *

    + * If the function fails, the return value is zero. To get extended + * error information, call {@link Kernel32#GetLastError()}.

    + */ + boolean GetIconInfo(HICON hIcon, ICONINFO piconinfo); + + /** + * Sends the specified message to one or more windows. + * + * @param hWnd + * A handle to the window whose window procedure will receive the + * message. + *

    + * If this parameter is HWND_BROADCAST ((HWND)0xffff), the + * message is sent to all top-level windows in the system, + * including disabled or invisible unowned windows. The function + * does not return until each window has timed out. Therefore, + * the total wait time can be up to the value of uTimeout + * multiplied by the number of top-level windows.

    + * @param msg + * The message to be sent. + * @param wParam + * Any additional message-specific information. + * @param lParam + * Any additional message-specific information. + * @param fuFlags + * The behavior of this function. This parameter can be one or + * more of the following values: {@link WinUser#SMTO_ABORTIFHUNG} + * etc. + * @param uTimeout + * The duration of the time-out period, in milliseconds. If the + * message is a broadcast message, each window can use the full + * time-out period. For example, if you specify a five second + * time-out period and there are three top-level windows that + * fail to process the message, you could have up to a 15 second + * delay. + * @param lpdwResult + * The result of the message processing. The value of this + * parameter depends on the message that is specified. + * @return If the function succeeds, the return value is nonzero. + * SendMessageTimeout does not provide information about individual + * windows timing out if HWND_BROADCAST is used. + *

    + * If the function fails or times out, the return value is 0. To get + * extended error information, call GetLastError. If GetLastError + * returns ERROR_TIMEOUT, then the function timed out. + *

    + * Windows 2000: If {@link Kernel32#GetLastError()} returns 0, then + * the function timed out. + */ + LRESULT SendMessageTimeout(HWND hWnd, int msg, WPARAM wParam, LPARAM lParam, + int fuFlags, int uTimeout, DWORDByReference lpdwResult); + + /** + * Retrieves the specified value from the WNDCLASSEX structure associated + * with the specified window. + * + * @param hWnd + * A handle to the window and, indirectly, the class to which the + * window belongs. + * @param nIndex + * The value to be retrieved. To retrieve a value from the extra + * class memory, specify the positive, zero-based byte offset of + * the value to be retrieved. Valid values are in the range zero + * through the number of bytes of extra class memory, minus + * eight; for example, if you specified 24 or more bytes of extra + * class memory, a value of 16 would be an index to the third + * integer.To retrieve any other value from the WNDCLASSEX + * structure, specify one of the following values: + * {@link WinUser#GCW_ATOM} etc. + * @return If the function succeeds, the return value is the requested + * value. + *

    + * If the function fails, the return value is zero. To get extended + * error information, call {@link Kernel32#GetLastError()}.

    + */ + ULONG_PTR GetClassLongPtr(HWND hWnd, int nIndex); + + /** + * @param pRawInputDeviceList + * An array of {@link WinUser.RAWINPUTDEVICELIST} structures for the devices + * attached to the system. If (@code null}, the number of devices is + * returned in puiNumDevices + * @param puiNumDevices + * If pRawInputDeviceList is {@code null}, the function populates + * this variable with the number of devices attached to the system; + * otherwise, this variable specifies the number of {@link WinUser.RAWINPUTDEVICELIST} + * structures that can be contained in the buffer to which pRawInputDeviceList + * points. If this value is less than the number of devices attached to + * the system, the function returns the actual number of devices in this + * variable and fails with ERROR_INSUFFICIENT_BUFFER. + * @param cbSize + * The size of a {@link WinUser.RAWINPUTDEVICELIST} structure, in bytes. + * @return If the function is successful, the return value is the number of devices + * stored in the buffer pointed to by pRawInputDeviceList. On + * any other error, the function returns -1 and {@code GetLastError} + * returns the error indication. + * @see WinUser.RAWINPUTDEVICELIST#sizeof() + * @see GetRawInputDeviceList + */ + int GetRawInputDeviceList(RAWINPUTDEVICELIST[] pRawInputDeviceList, IntByReference puiNumDevices, int cbSize); + + + /** + * Retrieves a handle to the desktop window. The desktop window covers the + * entire screen. The desktop window is the area on top of which other + * windows are painted. + * + * @return Type: HWND The return value is a handle to the desktop window. + */ + HWND GetDesktopWindow(); + + /** + * The PrintWindow function copies a visual window into the specified device + * context (DC), typically a printer DC. + * + * @param hWnd + * A handle to the window that will be copied. + * @param dest + * A handle to the destination device context. + * @param flags + * The drawing options. It can be one of the following values: + *
    + * PW_CLIENTONLY:
    + * Only the client area of the window is copied to hdcBlt. By + * default, the entire window is copied. + * @return If the function succeeds, it returns true (MSDN: a nonzero + * value). If the function fails, it returns false (MSDN: zero). + */ + boolean PrintWindow(HWND hWnd, HDC dest, int flags); + + /** + * Determines whether the specified window is enabled for mouse and keyboard + * input. + * + * @param hWnd + * A handle to the window to be tested. + * @return If the window is enabled, the return value is true (nonzero).
    + * If the window is not enabled, the return value is false (zero). + */ + boolean IsWindowEnabled(HWND hWnd); + + /** + * Determines whether the specified window handle identifies an existing + * window.
    + * A thread should not use IsWindow for a window that it did not create + * because the window could be destroyed after this function was called.
    + * Further, because window handles are recycled the handle could even point + * to a different window. + * + * @param hWnd + * A handle to the window to be tested. + * @return If the window handle identifies an existing window, the return + * value is true (nonzero).
    + * If the window handle does not identify an existing window, the + * return value is false (zero). + */ + boolean IsWindow(HWND hWnd); + + /** + * @param parent + * Type: HWND
    + * A handle to the parent window whose child windows are to be + * searched.
    + * If hwndParent is NULL, the function + * uses the desktop window as the parent window. The function + * searches among windows that are child windows of the desktop. + *
    + * If hwndParent is HWND_MESSAGE, the + * function searches all + * message-only windows.
    + * @param child + * Type: HWND
    + * A handle to a child window. The search begins with the next + * child window in the Z order. The child window must be a direct + * child window of hwndParent, not just a descendant + * window.
    + * If hwndChildAfter is NULL, the + * search begins with the first child window of + * hwndParent.
    + * Note that if both hwndParent and + * hwndChildAfter are NULL, the + * function searches all top-level and message-only windows.
    + * @param className + * Type: LPCTSTR
    + * The class name or a class atom created by a previous call to + * the + * RegisterClass + * or + * RegisterClassEx + * function. The atom must be placed in the + * low-order word of lpszClass; the high-order word must + * be zero.
    + * If lpszClass is a string, it specifies the window + * class name. The class name can be any name registered with + * + * RegisterClass + * or + * RegisterClassEx + * , or any of the predefined control-class names, + * or it can be MAKEINTATOM(0x8000). In this latter + * case, 0x8000 is the atom for a menu class. For more + * information, see the Remarks section of this topic.
    + * @param window + * Type: LPCTSTR
    + * The window name (the window's title). If this parameter is + * NULL, all window names match. + * @return If the function succeeds, the return value is a handle to the + * window that has the specified class and window names.
    + * If the function fails, the return value is NULL. To get extended + * error information, call GetLastError. + */ + HWND FindWindowEx(HWND parent, HWND child, String className, String window); + + /** + * Retrieves the handle to the ancestor of the specified window. + * + * @param hwnd + * A handle to the window whose ancestor is to be retrieved. If + * this parameter is the desktop window, the function returns + * NULL. + * @param gaFlags + * The ancestor to be retrieved. This parameter can be one of the + * following values:
    + *
      + *
    • GA_PARENT (1) -- Retrieves the parent window. This does + * not include the owner, as it does with the GetParent function. + *
    • + *
    • GA_ROOT (2) -- Retrieves the root window by walking the + * chain of parent windows..
    • + *
    • GA_ROOTOWNER (3) -- Retrieves the owned root window by + * walking the chain of parent and owner windows returned by + * GetParent..
    • + *
    + * @return The return value is the handle to the ancestor window. + */ + HWND GetAncestor(HWND hwnd, int gaFlags); + + /** + * Retrieves the position of the mouse cursor, in screen coordinates. + * + * @param p + * lpPoint [out]
    + * Type: LPPOINT
    + * A pointer to a POINT structure that receives the screen + * coordinates of the cursor. + * @return Type: BOOL.
    + * Returns nonzero if successful or zero otherwise. To get extended + * error information, call GetLastError. + */ + boolean GetCursorPos(POINT p); + + /** + * Moves the cursor to the specified screen coordinates.
    + * If the new coordinates are not within the screen rectangle set by the + * most recent ClipCursor function call, the system automatically adjusts + * the coordinates so that the cursor stays within the rectangle. + * + * @param x + * The new x-coordinate of the cursor, in screen coordinates. + * @param y + * The new y-coordinate of the cursor, in screen coordinates. + * @return Type: BOOL.
    + * Returns nonzero if successful or zero otherwise. To get extended + * error information, call GetLastError. + */ + boolean SetCursorPos(long x, long y); + + /** + * @param eventMin + * Type: UINT
    + * Specifies the event constant for the lowest event value in the + * range of events that are handled by the hook function.
    + * This parameter can be set to EVENT_MIN to indicate the lowest + * possible event value. + * @param eventMax + * Type: UINT
    + * Specifies the event constant for the highest event value in + * the range of events that are handled by the hook function.
    + * This parameter can be set to EVENT_MAX to indicate the highest + * possible event value. + * @param hmodWinEventProc + * Type: HMODULE
    + * Handle to the DLL that contains the hook function at + * lpfnWinEventProc, if the WINEVENT_INCONTEXT flag is specified + * in the dwFlags parameter.
    + * If the hook function is not located in a DLL, or if the + * WINEVENT_OUTOFCONTEXT flag is specified, this parameter is + * NULL. + * @param winEventProc + * Type: WINEVENTPROC
    + * Pointer to the event hook function. For more information about + * this function, see WinEventProc. + * @param processID + * Type: DWORD
    + * Specifies the ID of the process from which the hook function + * receives events.
    + * Specify zero (0) to receive events from all processes on the + * current desktop. + * @param threadID + * Type: DWORD
    + * Specifies the ID of the thread from which the hook function + * receives events.
    + * If this parameter is zero, the hook function is associated + * with all existing threads on the current desktop. + * @param flags + * Type: UINT
    + * Flag values that specify the location of the hook function and + * of the events to be skipped.
    + * The following flags are valid:
    + *
      + *
    • WINEVENT_INCONTEXT: The DLL that contains the + * callback function is mapped into the address space of the + * process that generates the event.
      + * With this flag, the system sends event notifications to the + * callback function as they occur.
      + * The hook function must be in a DLL when this flag is + * specified.
      + * This flag has no effect when both the calling process and the + * generating process are not 32-bit or 64-bit processes, or when + * the generating process is a console application.
      + * For more information, see In-Context Hook Functions.
    • + *
    • WINEVENT_OUTOFCONTEXT: The callback function is not + * mapped into the address space of the process that generates + * the event.
      + * Because the hook function is called across process boundaries, + * the system must queue events.
      + * Although this method is asynchronous, events are guaranteed to + * be in sequential order.
      + * For more information, see Out-of-Context Hook Functions.
    • + *
    • WINEVENT_SKIPOWNPROCESS:
      + * Prevents this instance of the hook from receiving the events + * that are generated by threads in this process.
      + * This flag does not prevent threads from generating events. + *
    • + *
    • WINEVENT_SKIPOWNTHREAD:
      + * Prevents this instance of the hook from receiving the events + * that are generated by the thread that is registering this + * hook.
    • + *
    + * @return Type: HWINEVENTHOOK
    + * If successful, returns an HWINEVENTHOOK value that identifies + * this event hook instance. Applications save this return value to + * use it with the UnhookWinEvent function.
    + * If unsuccessful, returns zero.
    + */ + HANDLE SetWinEventHook(int eventMin, int eventMax, HMODULE hmodWinEventProc, WinEventProc winEventProc, + int processID, int threadID, int flags); + + /** + * Removes an event hook function created by a previous call to + * SetWinEventHook. + * + * @param hook + * Type: HWINEVENTHOOK
    + * Handle to the event hook returned in the previous call to + * SetWinEventHook. + * @return Type: BOOL If successful, returns TRUE; otherwise, returns FALSE. + *
    + * Three common errors cause this function to fail:
    + * The hWinEventHook parameter is NULL or not valid.
    + * The event hook specified by hWinEventHook was already removed. + *
    + * UnhookWinEvent is called from a thread that is different from the + * original call to SetWinEventHook.
    + */ + boolean UnhookWinEvent(HANDLE hook); + + /** + * Copies the specified icon from another module to the current module. + * + * @param hIcon + * A handle to the icon to be copied. + * @return If the function succeeds, the return value is a handle to the + * duplicate icon.
    + * If the function fails, the return value is NULL. To get extended + * error information, call GetLastError. + * @see MSDN + */ + HICON CopyIcon(HICON hIcon); + + /** + * Retrieves the specified 32-bit (DWORD) value from the WNDCLASSEX + * structure associated with the specified window. Note If you are + * retrieving a pointer or a handle, this function has been superseded by + * the GetClassLongPtr function.
    + * (Pointers and handles are 32 bits on 32-bit Windows and 64 bits on 64-bit + * Windows.) + * + * @param hWnd + * A handle to the window and, indirectly, the class to which the + * window belongs. + * @param nIndex + * The value to be retrieved. To retrieve a value from the extra + * class memory, specify the positive, zero-based byte offset of + * the value to be retrieved. Valid values are in the range zero + * through the number of bytes of extra class memory, minus four; + * for example, if you specified 12 or more bytes of extra class + * memory, a value of 8 would be an index to the third integer. + * To retrieve any other value from the WNDCLASSEX structure, + * specify one of the following values. + * Retrieves an ATOM value that uniquely identifies the window + * class. This is the same atom that the RegisterClassEx function + * returns.
    + * GCL_CBCLSEXTRA: -20
    + * Retrieves the size, in bytes, of the extra memory associated + * with the class.
    + * GCL_CBWNDEXTRA: -18
    + * Retrieves the size, in bytes, of the extra window memory + * associated with each window in the class. For information on + * how to access this memory, see GetWindowLong.
    + * GCL_HBRBACKGROUND: -10
    + * Retrieves a handle to the background brush associated with the + * class.
    + * GCL_HCURSOR: -12
    + * Retrieves a handle to the cursor associated with the class. + *
    + * GCL_HICON: -14
    + * Retrieves a handle to the icon associated with the class.
    + * GCL_HICONSM: -34
    + * Retrieves a handle to the small icon associated with the + * class.
    + * GCL_HMODULE: -16
    + * Retrieves a handle to the module that registered the class. + *
    + * GCL_MENUNAME: -8
    + * Retrieves the address of the menu name string. The string + * identifies the menu resource associated with the class.
    + * GCL_STYLE: -26
    + * Retrieves the window-class style bits.
    + * GCL_WNDPROC: -24
    + * Retrieves the address of the window procedure, or a handle + * representing the address of the window procedure. You must use + * the CallWindowProc function to call the window procedure. + * @return Type: DWORD If the function succeeds, the return value is the + * requested value.
    + * If the function fails, the return value is zero. To get extended + * error information, call GetLastError.
    + */ + int GetClassLong(HWND hWnd, int nIndex); + + /** + * Registers a new clipboard format. This format can then be used as a + * valid clipboard format. + * + * @param formatName The name of the new format. + * + * @return If the function succeeds, the return value identifies the + * registered clipboard format. + * + *

    If the function fails, the return value is zero. To get extended + * error information, call GetLastError.

    + */ + public int RegisterClipboardFormat(String formatName); } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/User32Util.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/User32Util.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/User32Util.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/User32Util.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,24 +1,50 @@ /* * Copyright (c) 2013 Ralf Hamberger, Markus Karg, All Rights Reserved * - * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * 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 java.util.Arrays; import java.util.List; -import com.sun.jna.WString; import com.sun.jna.platform.win32.WinDef.HINSTANCE; import com.sun.jna.platform.win32.WinDef.HMENU; import com.sun.jna.platform.win32.WinDef.HWND; import com.sun.jna.platform.win32.WinDef.LPVOID; +import com.sun.jna.platform.win32.WinUser.MSG; import com.sun.jna.platform.win32.WinUser.RAWINPUTDEVICELIST; import com.sun.jna.ptr.IntByReference; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collections; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.FutureTask; +import java.util.logging.Level; +import java.util.logging.Logger; /** @@ -43,7 +69,7 @@ public static final HWND createWindowEx(final int exStyle, final String className, final String windowName, final int style, final int x, final int y, final int width, final int height, final HWND parent, final HMENU menu, final HINSTANCE instance, final LPVOID param) { final HWND hWnd = User32.INSTANCE - .CreateWindowEx(exStyle, new WString(className), windowName, style, x, y, width, height, parent, menu, instance, param); + .CreateWindowEx(exStyle, className, windowName, style, x, y, width, height, parent, menu, instance, param); if (hWnd == null) throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); return hWnd; @@ -77,4 +103,164 @@ return Arrays.asList(records); } -} \ No newline at end of file + + /** + * Helper class, that runs a windows message loop as a seperate thread. + * + * This is intended to be used in conjunction with APIs, that need a + * spinning message loop. One example for this are the DDE functions, that + * can only be used if a message loop is present. + * + * To enable interaction with the mainloop the MessageLoopThread allows to + * dispatch callables into the mainloop and let these Callables be invoked + * on the message thread. + * + * This implies, that the Callables should block the loop as short as possible. + */ + public static class MessageLoopThread extends Thread { + + public class Handler implements InvocationHandler { + + private final Object delegate; + + public Handler(Object delegate) { + this.delegate = delegate; + } + + public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable { + try { + return MessageLoopThread.this.runOnThread(new Callable() { + public Object call() throws Exception { + return method.invoke(delegate, args); + } + }); + } catch (InvocationTargetException ex) { + Throwable cause = ex.getCause(); + if (cause instanceof Exception) { + StackTraceElement[] hiddenStack = cause.getStackTrace(); + cause.fillInStackTrace(); + StackTraceElement[] currentStack = cause.getStackTrace(); + StackTraceElement[] fullStack = new StackTraceElement[currentStack.length + hiddenStack.length]; + System.arraycopy(hiddenStack, 0, fullStack, 0, hiddenStack.length); + System.arraycopy(currentStack, 0, fullStack, hiddenStack.length, currentStack.length); + cause.setStackTrace(fullStack); + throw (Exception) cause; + } else { + throw ex; + } + } + } + } + + private volatile int nativeThreadId = 0; + private volatile long javaThreadId = 0; + private final List workQueue = Collections.synchronizedList(new ArrayList()); + + @Override + public void run() { + MSG msg = new WinUser.MSG(); + + // Make sure message loop is prepared + User32.INSTANCE.PeekMessage(msg, null, 0, 0, 0); + javaThreadId = Thread.currentThread().getId(); + nativeThreadId = Kernel32.INSTANCE.GetCurrentThreadId(); + + int getMessageReturn; + while ((getMessageReturn = User32.INSTANCE.GetMessage(msg, null, 0, 0)) != 0) { + if (getMessageReturn != -1) { + // Normal processing + while (!workQueue.isEmpty()) { + try { + FutureTask ft = workQueue.remove(0); + ft.run(); + } catch (IndexOutOfBoundsException ex) { + break; + } + } + User32.INSTANCE.TranslateMessage(msg); + User32.INSTANCE.DispatchMessage(msg); + } else { + // Error case + if(getMessageFailed()) { + break; + } + } + } + + while (!workQueue.isEmpty()) { + workQueue.remove(0).cancel(false); + } + } + + public Future runAsync(Callable command) { + while(nativeThreadId == 0) { + try { + Thread.sleep(20); + } catch (InterruptedException ex) { + Logger.getLogger(MessageLoopThread.class.getName()).log(Level.SEVERE, null, ex); + } + } + FutureTask futureTask = new FutureTask(command); + workQueue.add(futureTask); + User32.INSTANCE.PostThreadMessage(nativeThreadId, WinUser.WM_USER, null, null); + return futureTask; + } + + public V runOnThread(Callable callable) throws Exception { + while (javaThreadId == 0) { + try { + Thread.sleep(20); + } catch (InterruptedException ex) { + Logger.getLogger(MessageLoopThread.class.getName()).log(Level.SEVERE, null, ex); + } + } + + if(javaThreadId == Thread.currentThread().getId()) { + return callable.call(); + } else { + + Future ft = runAsync(callable); + try { + return ft.get(); + } catch (InterruptedException ex) { + throw ex; + } catch (ExecutionException ex) { + Throwable cause = ex.getCause(); + if (cause instanceof Exception) { + throw (Exception) cause; + } else { + throw ex; + } + } + } + } + + public void exit() { + User32.INSTANCE.PostThreadMessage(nativeThreadId, WinUser.WM_QUIT, null, null); + } + + /** + * The method is called from the thread, that run the message dispatcher, + * when the call to {@link com.sun.jna.platform.win32.User32#GetMessage} + * fails (returns {@code -1}). + * + *

    If the method returns {@code true}, the MainLoop is exitted, if it + * returns {@code false} the mainloop is resumed.

    + * + *

    Default behavior: The error code is logged to the + * com.sun.jna.platform.win32.User32Util.MessageLoopThread logger and + * the main loop exists. + *

    + * + * @return true if MainLoop should exit, false it it should resume + */ + protected boolean getMessageFailed() { + int lastError = Kernel32.INSTANCE.GetLastError(); + Logger.getLogger("com.sun.jna.platform.win32.User32Util.MessageLoopThread") + .log(Level.WARNING, + "Message loop was interrupted by an error. [lastError: {0}]", + lastError); + return true; + } + } +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Variant.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Variant.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Variant.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Variant.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,10 +1,31 @@ +/* + * 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 java.util.Arrays; +import com.sun.jna.IntegerType; import java.util.Date; import java.util.List; -import com.sun.jna.IntegerType; import com.sun.jna.Pointer; import com.sun.jna.Structure; import com.sun.jna.Union; @@ -40,7 +61,6 @@ import com.sun.jna.platform.win32.WinDef.USHORTByReference; import com.sun.jna.platform.win32.COM.Dispatch; import com.sun.jna.platform.win32.COM.IDispatch; -import com.sun.jna.platform.win32.COM.IRecordInfo; import com.sun.jna.platform.win32.COM.Unknown; import com.sun.jna.ptr.ByteByReference; import com.sun.jna.ptr.DoubleByReference; @@ -106,12 +126,14 @@ public static VARIANT_BOOL VARIANT_TRUE = new VARIANT_BOOL(0xFFFF); public static VARIANT_BOOL VARIANT_FALSE = new VARIANT_BOOL(0x0000); + @Deprecated public final static long COM_DAYS_ADJUSTMENT = 25569L; // ((1969 - 1899) * // 365) +1 + Leap - // years = Days + // years = Days + @Deprecated public final static long MICRO_SECONDS_PER_DAY = 86400000L; // 24L * 60L * // 60L * 1000L; - + public static class VARIANT extends Union { public static class ByReference extends VARIANT implements @@ -144,6 +166,13 @@ } } + public static final VARIANT VARIANT_MISSING; + + static { + VARIANT_MISSING = new VARIANT(); + VARIANT_MISSING.setValue(VT_ERROR, new SCODE(WinError.DISP_E_PARAMNOTFOUND)); + } + public _VARIANT _variant; public DECIMAL decVal; @@ -171,12 +200,11 @@ public VARIANT(VARIANT_BOOL value) { this(); - this.setValue(VT_BOOL, new BOOL(value.intValue())); + this.setValue(VT_BOOL, value); } public VARIANT(BOOL value) { - this(); - this.setValue(VT_BOOL, value); + this(value.booleanValue()); } public VARIANT(LONG value) { @@ -197,16 +225,17 @@ public VARIANT(byte value) { this(new BYTE(value)); } - + public VARIANT(BYTE value) { this(); this.setValue(Variant.VT_UI1, value); } public VARIANT(char value) { - this(new CHAR(value)); + this(); + this.setValue(VT_UI2, new USHORT(value)); } - + public VARIANT(CHAR value) { this(); this.setValue(Variant.VT_I1, value); @@ -216,7 +245,7 @@ this(); this.setValue(VT_I2, new SHORT(value)); } - + public VARIANT(int value) { this(); this.setValue(VT_I4, new LONG(value)); @@ -237,6 +266,16 @@ this.setValue(VT_R8, value); } + /** + * Create a new VARIANT wrapping the supplied string. + * + *

    Implementation note: the string is wrapped as a BSTR value, + * that is allocated using {@link com.sun.jna.platform.win32.OleAuto#SysAllocString} + * and needs to be freed using + * {@link com.sun.jna.platform.win32.OleAuto#SysFreeString} by the user

    + * + * @param value to be wrapped + */ public VARIANT(String value) { this(); BSTR bstrValue = OleAuto.INSTANCE.SysAllocString(value); @@ -245,10 +284,7 @@ public VARIANT(boolean value) { this(); - if (value) - this.setValue(VT_BOOL, new BOOL(VARIANT_TRUE.intValue())); - else - this.setValue(VT_BOOL, new BOOL(VARIANT_FALSE.intValue())); + this.setValue(VT_BOOL, new VARIANT_BOOL(value)); } public VARIANT(IDispatch value) { @@ -262,6 +298,11 @@ this.setValue(VT_DATE, date); } + public VARIANT(SAFEARRAY array) { + this(); + this.setValue(array); + } + public VARTYPE getVarType() { this.read(); return _variant.vt; @@ -274,9 +315,14 @@ public void setValue(int vt, Object value) { this.setValue(new VARTYPE(vt), value); } + + public void setValue(SAFEARRAY array) { + this.setValue(array.getVarType().intValue() | VT_ARRAY, array); + } public void setValue(VARTYPE vt, Object value) { - switch (vt.intValue()) { + int varType = vt.intValue(); + switch (varType) { case VT_UI1: this._variant.__variant.writeField("bVal", value); break; @@ -316,12 +362,6 @@ case VT_DISPATCH: this._variant.__variant.writeField("pdispVal", value); break; - case VT_SAFEARRAY: - this._variant.__variant.writeField("parray", value); - break; - case VT_ARRAY: - this._variant.__variant.writeField("parray", value); - break; case VT_BYREF | VT_UI1: this._variant.__variant.writeField("pbVal", value); break; @@ -361,9 +401,6 @@ case VT_BYREF | VT_DISPATCH: this._variant.__variant.writeField("ppdispVal", value); break; - case VT_BYREF | VT_ARRAY: - this._variant.__variant.writeField("pparray", value); - break; case VT_BYREF | VT_VARIANT: this._variant.__variant.writeField("pvarVal", value); break; @@ -412,6 +449,14 @@ case VT_RECORD: this._variant.__variant.writeField("pvRecord", value); break; + default: + if ((varType & VT_ARRAY) > 0) { + if ((varType & VT_BYREF) > 0) { + this._variant.__variant.writeField("pparray", value); + } else { + this._variant.__variant.writeField("parray", value); + } + } } this._variant.writeField("vt", vt); @@ -420,7 +465,10 @@ public Object getValue() { this.read(); + int varType = this.getVarType().intValue(); switch (this.getVarType().intValue()) { + case VT_UI1: + return this._variant.__variant.readField("bVal"); case VT_I2: return this._variant.__variant.readField("iVal"); case VT_I4: @@ -445,10 +493,6 @@ return this._variant.__variant.readField("punkVal"); case VT_DISPATCH: return this._variant.__variant.readField("pdispVal"); - case VT_SAFEARRAY: - return this._variant.__variant.readField("parray"); - case VT_ARRAY: - return this._variant.__variant.readField("parray"); case VT_BYREF | VT_UI1: return this._variant.__variant.readField("pbVal"); case VT_BYREF | VT_I2: @@ -475,8 +519,6 @@ return this._variant.__variant.readField("ppunkVal"); case VT_BYREF | VT_DISPATCH: return this._variant.__variant.readField("ppdispVal"); - case VT_BYREF | VT_ARRAY: - return this._variant.__variant.readField("pparray"); case VT_BYREF | VT_VARIANT: return this._variant.__variant.readField("pvarVal"); case VT_BYREF: @@ -510,85 +552,103 @@ case VT_RECORD: return this._variant.__variant.readField("pvRecord"); default: + if((varType & VT_ARRAY) > 0) { + if((varType & VT_BYREF) > 0) { + return this._variant.__variant.readField("pparray"); + } else { + return this._variant.__variant.readField("parray"); + } + } return null; } } - public int shortValue() { - return (Short) this.getValue(); + public byte byteValue() { + return ((Number) this.getValue()).byteValue(); + } + + public short shortValue() { + return ((Number) this.getValue()).shortValue(); } public int intValue() { - return (Integer) this.getValue(); + return ((Number) this.getValue()).intValue(); } public long longValue() { - return (Long) this.getValue(); + return ((Number) this.getValue()).longValue(); } public float floatValue() { - return (Float) this.getValue(); + return ((Number) this.getValue()).floatValue(); } public double doubleValue() { - return (Double) this.getValue(); + return ((Number) this.getValue()).doubleValue(); } public String stringValue() { BSTR bstr = (BSTR) this.getValue(); - return bstr.getValue(); + if(bstr == null) { + return null; + } else { + return bstr.getValue(); + } } public boolean booleanValue() { - return (Boolean) this.getValue(); + // getValue returns a VARIANT_BOOL + return ((VARIANT_BOOL) this.getValue()).booleanValue(); } public Date dateValue() { DATE varDate = (DATE) this.getValue(); - return this.toJavaDate(varDate); + if(varDate == null) { + return null; + } else { + return varDate.getAsJavaDate(); + } } + @Deprecated protected Date toJavaDate(DATE varDate) { - - double doubleDate = varDate.date; - long longDate = (long) doubleDate; - - double doubleTime = doubleDate - longDate; - long longTime = (long) doubleTime * MICRO_SECONDS_PER_DAY; - - return new Date( - ((longDate - COM_DAYS_ADJUSTMENT) * MICRO_SECONDS_PER_DAY) - + longTime); + return varDate.getAsJavaDate(); } + @Deprecated protected DATE fromJavaDate(Date javaDate) { - long longTime = javaDate.getTime() % MICRO_SECONDS_PER_DAY; - long longDate = ((javaDate.getTime() - longTime) / MICRO_SECONDS_PER_DAY) - + COM_DAYS_ADJUSTMENT; - - float floatTime = ((float) longTime) - / ((float) MICRO_SECONDS_PER_DAY); - float floatDateTime = floatTime + longDate; - return new DATE(floatDateTime); + return new DATE(javaDate); } public static class _VARIANT extends Structure { + public static final List FIELDS = createFieldsOrder("vt", + "wReserved1", "wReserved2", "wReserved3", "__variant"); - public VARTYPE vt; - public short wReserved1; - public short wReserved2; - public short wReserved3; - public __VARIANT __variant; + public static class __VARIANT extends Union { + public static class BRECORD extends Structure { + public static class ByReference extends BRECORD implements + Structure.ByReference { + } - public _VARIANT() { - } + public static final List FIELDS = createFieldsOrder("pvRecord", "pRecInfo"); - public _VARIANT(Pointer pointer) { - super(pointer); - this.read(); - } + public PVOID pvRecord; + public Pointer pRecInfo; + + public BRECORD() { + super(); + } + + public BRECORD(Pointer pointer) { + super(pointer); + } + + @Override + protected List getFieldOrder() { + return FIELDS; + } + } - public static class __VARIANT extends Union { // LONGLONG VT_I8 public LONGLONG llVal; // LONG VT_I4 @@ -602,7 +662,7 @@ // DOUBLE VT_R8 public Double dblVal; // VARIANT_BOOL VT_BOOL - public BOOL boolVal; + public VARIANT_BOOL boolVal; // SCODE VT_ERROR public SCODE scode; // CY VT_CY @@ -679,29 +739,6 @@ public UINTByReference puintVal; // BRECORD VT_RECORD public BRECORD pvRecord; - - public static class BRECORD extends Structure { - public static class ByReference extends BRECORD implements - Structure.ByReference { - } - - public PVOID pvRecord; - - public Pointer pRecInfo; - - public BRECORD() { - } - - public BRECORD(Pointer pointer) { - super(pointer); - } - - @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "pvRecord", - "pRecInfo" }); - } - } public __VARIANT() { super(); @@ -714,10 +751,24 @@ } } + public VARTYPE vt; + public short wReserved1; + public short wReserved2; + public short wReserved3; + public __VARIANT __variant; + + public _VARIANT() { + super(); + } + + public _VARIANT(Pointer pointer) { + super(pointer); + this.read(); + } + @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "vt", "wReserved1", - "wReserved2", "wReserved3", "__variant" }); + protected List getFieldOrder() { + return FIELDS; } } } @@ -734,9 +785,11 @@ } } + public static final List FIELDS = createFieldsOrder("variantArg"); public VARIANT[] variantArg = new VARIANT[1]; public VariantArg() { + super(); } /** @@ -746,21 +799,21 @@ public VariantArg(Pointer pointer) { super(pointer); } - + public VariantArg(VARIANT[] variantArg) { this.variantArg = variantArg; } @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "variantArg" }); + protected List getFieldOrder() { + return FIELDS; } - + public void setArraySize(int size) { this.variantArg = new VARIANT[size]; this.read(); } - + } } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/VerRsrc.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/VerRsrc.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/VerRsrc.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/VerRsrc.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,26 +1,35 @@ -/* This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. +/* 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 java.util.Arrays; import java.util.List; import com.sun.jna.Pointer; import com.sun.jna.Structure; -import com.sun.jna.win32.StdCallLibrary; /** * Interface for the VerRsrc.h header file. */ -public interface VerRsrc extends StdCallLibrary { +public interface VerRsrc { /** * Contains version information for a file. This information is language and code page independent. @@ -36,13 +45,13 @@ } } - public VS_FIXEDFILEINFO() { - } - - public VS_FIXEDFILEINFO(Pointer memory) { - super(memory); - read(); - } + public static final List FIELDS = createFieldsOrder( + "dwSignature", "dwStrucVersion", + "dwFileVersionMS", "dwFileVersionLS", + "dwProductVersionMS", "dwProductVersionLS", + "dwFileFlagsMask", "dwFileFlags", "dwFileOS", + "dwFileType", "dwFileSubtype", + "dwFileDateMS", "dwFileDateLS"); /** * Contains the value 0xFEEF04BD. This is used with the szKey member of the VS_VERSIONINFO structure when @@ -116,9 +125,51 @@ * The least significant 32 bits of the file's 64-bit binary creation date and time stamp. */ public WinDef.DWORD dwFileDateLS; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "dwSignature", "dwStrucVersion", "dwFileVersionMS", "dwFileVersionLS", "dwProductVersionMS", "dwProductVersionLS", "dwFileFlagsMask", "dwFileFlags", "dwFileOS", "dwFileType", "dwFileSubtype", "dwFileDateMS", "dwFileDateLS" }); + + public VS_FIXEDFILEINFO() { + super(); + } + + public VS_FIXEDFILEINFO(Pointer memory) { + super(memory); + read(); + } + + public int getFileVersionMajor() { + return dwFileVersionMS.intValue() >>> 16; + } + + public int getFileVersionMinor() { + return dwFileVersionMS.intValue() & 0xffff; + } + + public int getFileVersionRevision() { + return dwFileVersionLS.intValue() >>> 16; + } + + public int getFileVersionBuild() { + return dwFileVersionLS.intValue() & 0xffff; + } + + public int getProductVersionMajor() { + return dwProductVersionMS.intValue() >>> 16; + } + + public int getProductVersionMinor() { + return dwProductVersionMS.intValue() & 0xffff; + } + + public int getProductVersionRevision() { + return dwProductVersionLS.intValue() >>> 16; + } + + public int getProductVersionBuild() { + return dwProductVersionLS.intValue() & 0xffff; + } + + @Override + protected List getFieldOrder() { + return FIELDS; } } } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Version.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Version.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Version.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Version.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,12 +1,23 @@ -/* This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. +/* 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; @@ -22,8 +33,7 @@ */ public interface Version extends StdCallLibrary { - Version INSTANCE = (Version) - Native.loadLibrary("version", Version.class, W32APIOptions.DEFAULT_OPTIONS); + Version INSTANCE = Native.loadLibrary("version", Version.class, W32APIOptions.DEFAULT_OPTIONS); /** * Determines whether the operating system can retrieve version information for a specified file. If version diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/VersionUtil.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/VersionUtil.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/VersionUtil.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/VersionUtil.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,88 @@ +/* Copyright (c) 2015 Michael Freeman, 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.Memory; +import com.sun.jna.Native; +import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.VerRsrc.VS_FIXEDFILEINFO; +import com.sun.jna.platform.win32.Version; +import com.sun.jna.platform.win32.Win32Exception; +import com.sun.jna.ptr.IntByReference; +import com.sun.jna.ptr.PointerByReference; + +/** + * Reads Windows Version info from files (the version details you can see by + * right-clicking and choosing properties) + * + * @author mlfreeman[at]gmail.com + */ +public class VersionUtil { + + /** + * Gets the file's version number info + * + * @param filePath + * The path to the file + * @return The VS_FIXEDFILEINFO structure read from the file.
    + * Use the getFileVersionMajor(), getFileVersionMinor(), + * getFileVersionRevision(), and getFileVersionBuild() + * @throws UnsupportedOperationException + * if VerQueryValue fails to get version info from the file. + */ + public static VS_FIXEDFILEINFO getFileVersionInfo(String filePath) { + IntByReference dwDummy = new IntByReference(); + + int versionLength = Version.INSTANCE.GetFileVersionInfoSize(filePath, dwDummy); + + // Reading version info failed. + // throw a Win32Exception with GetLastError() + if (versionLength == 0) { + throw new Win32Exception(Native.getLastError()); + } + + // buffer to hold version info + Pointer lpData = new Memory(versionLength); + + // pointer to pointer to location in aforementioned buffer + PointerByReference lplpBuffer = new PointerByReference(); + + if (!Version.INSTANCE.GetFileVersionInfo(filePath, 0, versionLength, lpData)) { + throw new Win32Exception(Native.getLastError()); + } + + // here to make VerQueryValue happy. + IntByReference puLen = new IntByReference(); + + // this does not set GetLastError, so no need to throw a Win32Exception + if (!Version.INSTANCE.VerQueryValue(lpData, "\\", lplpBuffer, puLen)) { + throw new UnsupportedOperationException("Unable to extract version info from the file: \"" + filePath + "\""); + } + + VS_FIXEDFILEINFO fileInfo = new VS_FIXEDFILEINFO(lplpBuffer.getValue()); + fileInfo.read(); + return fileInfo; + } + +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/W32Errors.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/W32Errors.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/W32Errors.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/W32Errors.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2010,2011 Daniel Doubrovkine, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/W32FileMonitor.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/W32FileMonitor.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/W32FileMonitor.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/W32FileMonitor.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * You can freely decide which license you want to apply to + * the project. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; @@ -27,9 +38,9 @@ import com.sun.jna.ptr.PointerByReference; public class W32FileMonitor extends FileMonitor { - + private static final int BUFFER_SIZE = 4096; - + private class FileInfo { public final File file; public final HANDLE handle; @@ -50,7 +61,7 @@ private final Map fileMap = new HashMap(); private final Map handleMap = new HashMap(); private boolean disposing = false; - + private void handleChanges(FileInfo finfo) throws IOException { Kernel32 klib = Kernel32.INSTANCE; FILE_NOTIFY_INFORMATION fni = finfo.info; @@ -63,51 +74,51 @@ case 0: break; case WinNT.FILE_ACTION_MODIFIED: - event = new FileEvent(file, FILE_MODIFIED); + event = new FileEvent(file, FILE_MODIFIED); break; case WinNT.FILE_ACTION_ADDED: - event = new FileEvent(file, FILE_CREATED); + event = new FileEvent(file, FILE_CREATED); break; case WinNT.FILE_ACTION_REMOVED: - event = new FileEvent(file, FILE_DELETED); + event = new FileEvent(file, FILE_DELETED); break; case WinNT.FILE_ACTION_RENAMED_OLD_NAME: - event = new FileEvent(file, FILE_NAME_CHANGED_OLD); + event = new FileEvent(file, FILE_NAME_CHANGED_OLD); break; case WinNT.FILE_ACTION_RENAMED_NEW_NAME: - event = new FileEvent(file, FILE_NAME_CHANGED_NEW); + event = new FileEvent(file, FILE_NAME_CHANGED_NEW); break; default: // TODO: other actions... System.err.println("Unrecognized file action '" + fni.Action + "'"); } - + if (event != null) { notify(event); } - + fni = fni.next(); } while (fni != null); - + // trigger the next read if (!finfo.file.exists()) { unwatch(finfo.file); return; } - - if (!klib.ReadDirectoryChangesW(finfo.handle, finfo.info, - finfo.info.size(), finfo.recursive, finfo.notifyMask, - finfo.infoLength, finfo.overlapped, null)) { + + if (!klib.ReadDirectoryChangesW(finfo.handle, finfo.info, + finfo.info.size(), finfo.recursive, finfo.notifyMask, + finfo.infoLength, finfo.overlapped, null)) { if (! disposing) { int err = klib.GetLastError(); throw new IOException("ReadDirectoryChangesW failed on " - + finfo.file + ": '" + + finfo.file + ": '" + Kernel32Util.formatMessageFromLastErrorCode(err) + "' (" + err + ")"); } } } - + private FileInfo waitForChange() { IntByReference rcount = new IntByReference(); ULONG_PTRByReference rkey = new ULONG_PTRByReference(); @@ -115,11 +126,11 @@ if (! Kernel32.INSTANCE.GetQueuedCompletionStatus(port, rcount, rkey, roverlap, WinBase.INFINITE)) { return null; } - synchronized (this) { + synchronized (this) { return handleMap.get(new HANDLE(rkey.getValue().toPointer())); } } - + private int convertMask(int mask) { int result = 0; if ((mask & FILE_CREATED) != 0) { @@ -151,6 +162,7 @@ private static int watcherThreadID; + @Override protected synchronized void watch(File file, int eventMask, boolean recursive) throws IOException { File dir = file; if (!dir.isDirectory()) { @@ -169,12 +181,12 @@ | WinNT.FILE_SHARE_WRITE | WinNT.FILE_SHARE_DELETE; int flags = WinNT.FILE_FLAG_BACKUP_SEMANTICS | WinNT.FILE_FLAG_OVERLAPPED; - HANDLE handle = klib.CreateFile(file.getAbsolutePath(), + HANDLE handle = klib.CreateFile(file.getAbsolutePath(), WinNT.FILE_LIST_DIRECTORY, mask, null, WinNT.OPEN_EXISTING, flags, null); if (WinBase.INVALID_HANDLE_VALUE.equals(handle)) { - throw new IOException("Unable to open " + file + " (" + throw new IOException("Unable to open " + file + " (" + klib.GetLastError() + ")"); } int notifyMask = convertMask(eventMask); @@ -188,10 +200,10 @@ + "for " + file + " (" + klib.GetLastError() + ")"); } - // TODO: use FileIOCompletionRoutine callback method instead of a + // TODO: use FileIOCompletionRoutine callback method instead of a // dedicated thread - if (!klib.ReadDirectoryChangesW(handle, finfo.info, finfo.info.size(), - recursive, notifyMask, finfo.infoLength, + if (!klib.ReadDirectoryChangesW(handle, finfo.info, finfo.info.size(), + recursive, notifyMask, finfo.infoLength, finfo.overlapped, null)) { int err = klib.GetLastError(); throw new IOException("ReadDirectoryChangesW failed on " @@ -201,6 +213,7 @@ } if (watcher == null) { watcher = new Thread("W32 File Monitor-" + (watcherThreadID++)) { + @Override public void run() { FileInfo finfo; while (true) { @@ -214,7 +227,7 @@ } continue; } - + try { handleChanges(finfo); } @@ -230,28 +243,30 @@ } } + @Override protected synchronized void unwatch(File file) { FileInfo finfo = fileMap.remove(file); if (finfo != null) { handleMap.remove(finfo.handle); Kernel32 klib = Kernel32.INSTANCE; // bug: the watcher may still be processing this file - klib.CloseHandle(finfo.handle); + klib.CloseHandle(finfo.handle); // TODO check error code if failed to close } } - + + @Override public synchronized void dispose() { disposing = true; - + // unwatch any remaining files in map, allows watcher thread to exit int i = 0; for (Object[] keys = fileMap.keySet().toArray(); !fileMap.isEmpty();) { unwatch((File)keys[i++]); } - + Kernel32 klib = Kernel32.INSTANCE; klib.PostQueuedCompletionStatus(port, 0, null, null); - klib.CloseHandle(port); + klib.CloseHandle(port); // TODO check error code if failed to close port = null; watcher = null; } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/W32FileUtils.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/W32FileUtils.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/W32FileUtils.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/W32FileUtils.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,21 +1,31 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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 java.io.File; import java.io.IOException; -import com.sun.jna.WString; import com.sun.jna.platform.FileUtils; public class W32FileUtils extends FileUtils { @@ -32,7 +42,7 @@ for (int i=0;i < paths.length;i++) { paths[i] = files[i].getAbsolutePath(); } - fileop.pFrom = new WString(fileop.encodePaths(paths)); + fileop.pFrom = fileop.encodePaths(paths); fileop.fFlags = ShellAPI.FOF_ALLOWUNDO|ShellAPI.FOF_NO_UI; int ret = shell.SHFileOperation(fileop); if (ret != 0) { diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/W32Service.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/W32Service.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/W32Service.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/W32Service.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,23 +1,52 @@ /* Copyright (c) 2010 EugineLev, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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 java.util.List; + +import com.sun.jna.Memory; +import com.sun.jna.Native; +import com.sun.jna.Pointer; +import com.sun.jna.Structure; +import com.sun.jna.WString; +import com.sun.jna.platform.win32.WinDef.DWORD; +import com.sun.jna.platform.win32.WinNT; +import com.sun.jna.platform.win32.WinNT.HANDLE; +import com.sun.jna.platform.win32.WinNT.HANDLEByReference; +import com.sun.jna.platform.win32.WinNT.LUID; +import com.sun.jna.platform.win32.WinNT.LUID_AND_ATTRIBUTES; +import com.sun.jna.platform.win32.WinNT.TOKEN_PRIVILEGES; +import com.sun.jna.platform.win32.Winsvc.SC_ACTION; import com.sun.jna.platform.win32.Winsvc.SC_HANDLE; import com.sun.jna.platform.win32.Winsvc.SC_STATUS_TYPE; +import com.sun.jna.platform.win32.Winsvc.SERVICE_FAILURE_ACTIONS; +import com.sun.jna.platform.win32.Winsvc.SERVICE_FAILURE_ACTIONS_FLAG; import com.sun.jna.platform.win32.Winsvc.SERVICE_STATUS_PROCESS; import com.sun.jna.ptr.IntByReference; + /** * Win32 Service wrapper * @author EugineLev @@ -46,7 +75,103 @@ _handle = null; } } - + + private void addShutdownPrivilegeToProcess() { + HANDLEByReference hToken = new HANDLEByReference(); + LUID luid = new LUID(); + Advapi32.INSTANCE.OpenProcessToken(Kernel32.INSTANCE.GetCurrentProcess(), + WinNT.TOKEN_ADJUST_PRIVILEGES, hToken); + Advapi32.INSTANCE.LookupPrivilegeValue("", WinNT.SE_SHUTDOWN_NAME, luid); + TOKEN_PRIVILEGES tp = new TOKEN_PRIVILEGES(1); + tp.Privileges[0] = new LUID_AND_ATTRIBUTES(luid, new DWORD(WinNT.SE_PRIVILEGE_ENABLED)); + Advapi32.INSTANCE.AdjustTokenPrivileges(hToken.getValue(), false, tp, tp.size(), null, + new IntByReference()); + } + + /** + * Set the failure actions of the specified service. Corresponds to + * ChangeServiceConfig2 + * with parameter dwInfoLevel set to SERVICE_CONFIG_FAILURE_ACTIONS. + */ + public void setFailureActions(List actions, int resetPeriod, String rebootMsg, + String command) { + SERVICE_FAILURE_ACTIONS.ByReference actionStruct = new SERVICE_FAILURE_ACTIONS.ByReference(); + actionStruct.dwResetPeriod = resetPeriod; + actionStruct.lpRebootMsg = rebootMsg; + actionStruct.lpCommand = command; + actionStruct.cActions = actions.size(); + + actionStruct.lpsaActions = new SC_ACTION.ByReference(); + SC_ACTION[] actionArray = (SC_ACTION[])actionStruct.lpsaActions.toArray(actions.size()); + boolean hasShutdownPrivilege = false; + int i = 0; + for (SC_ACTION action : actions) { + if (!hasShutdownPrivilege && action.type == Winsvc.SC_ACTION_REBOOT) { + addShutdownPrivilegeToProcess(); + hasShutdownPrivilege = true; + } + actionArray[i].type = action.type; + actionArray[i].delay = action.delay; + i++; + } + + if (!Advapi32.INSTANCE.ChangeServiceConfig2(_handle, Winsvc.SERVICE_CONFIG_FAILURE_ACTIONS, + actionStruct)) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + } + + private Pointer queryServiceConfig2(int type) { + IntByReference bufferSize = new IntByReference(); + Advapi32.INSTANCE.QueryServiceConfig2(_handle, type, Pointer.NULL, 0, bufferSize); + + Pointer buffer = new Memory(bufferSize.getValue()); + + if (!Advapi32.INSTANCE.QueryServiceConfig2(_handle, type, buffer, bufferSize.getValue(), + new IntByReference())) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + return buffer; + } + + /** + * Get the failure actions of the specified service. Corresponds to + * QueryServiceConfig2 + * with parameter dwInfoLevel set to SERVICE_CONFIG_FAILURE_ACTIONS. + */ + public SERVICE_FAILURE_ACTIONS getFailureActions() { + Pointer buffer = queryServiceConfig2(Winsvc.SERVICE_CONFIG_FAILURE_ACTIONS); + SERVICE_FAILURE_ACTIONS result = new SERVICE_FAILURE_ACTIONS(buffer); + return result; + } + + /** + * Set the failure action flag of the specified service. Corresponds to + * ChangeServiceConfig2 + * with parameter dwInfoLevel set to SERVICE_CONFIG_FAILURE_ACTIONS_FLAG. + */ + public void setFailureActionsFlag(boolean flagValue) { + SERVICE_FAILURE_ACTIONS_FLAG flag = new SERVICE_FAILURE_ACTIONS_FLAG(); + flag.fFailureActionsOnNonCrashFailures = flagValue ? 1 : 0; + + if (!Advapi32.INSTANCE.ChangeServiceConfig2(_handle, Winsvc.SERVICE_CONFIG_FAILURE_ACTIONS_FLAG, + flag)) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + } + + /** + * Get the failure actions flag of the specified service. Corresponds to + * QueryServiceConfig2 + * with parameter dwInfoLevel set to SERVICE_CONFIG_FAILURE_ACTIONS_FLAG. + */ + public boolean getFailureActionsFlag() { + Pointer buffer = queryServiceConfig2(Winsvc.SERVICE_CONFIG_FAILURE_ACTIONS_FLAG); + SERVICE_FAILURE_ACTIONS_FLAG result = new SERVICE_FAILURE_ACTIONS_FLAG(buffer); + return result.fFailureActionsOnNonCrashFailures != 0; + } + /** * Retrieves the current status of the specified service based on the specified information level. * @return diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/W32ServiceManager.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/W32ServiceManager.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/W32ServiceManager.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/W32ServiceManager.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2010 EugineLev, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Wdm.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Wdm.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Wdm.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Wdm.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,54 +1,50 @@ /* 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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 java.util.Arrays; import java.util.List; import com.sun.jna.Native; import com.sun.jna.Pointer; import com.sun.jna.Structure; -import com.sun.jna.win32.StdCallLibrary; /** * Ported from Wdm.h. * Microsoft Windows DDK. * @author dblock[at]dblock.org */ -public interface Wdm extends StdCallLibrary { - +public interface Wdm { + /** - * The KEY_BASIC_INFORMATION structure defines a subset of + * The KEY_BASIC_INFORMATION structure defines a subset of * the full information that is available for a registry key. */ - public static class KEY_BASIC_INFORMATION extends Structure { - public KEY_BASIC_INFORMATION() { - super(); - } + public static class KEY_BASIC_INFORMATION extends Structure { + public static final List FIELDS = createFieldsOrder("LastWriteTime", "TitleIndex", "NameLength", "Name"); - public KEY_BASIC_INFORMATION(int size) { - NameLength = size - 16; // write time, title index and name length - Name = new char[NameLength]; - allocateMemory(); - } - - public KEY_BASIC_INFORMATION(Pointer memory) { - super(memory); - read(); - } - /** - * The last time the key or any of its values changed. + * The last time the key or any of its values changed. */ public long LastWriteTime; /** @@ -56,17 +52,33 @@ */ public int TitleIndex; /** - * Specifies the size in bytes of the following name. + * Specifies the size in bytes of the following name. */ public int NameLength; /** - * A string of Unicode characters naming the key. + * A string of Unicode characters naming the key. * The string is not null-terminated. */ public char[] Name; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "LastWriteTime", "TitleIndex", "NameLength", "Name" }); + + public KEY_BASIC_INFORMATION() { + super(); + } + + public KEY_BASIC_INFORMATION(int size) { + NameLength = size - 16; // write time, title index and name length + Name = new char[NameLength]; + allocateMemory(); + } + + public KEY_BASIC_INFORMATION(Pointer memory) { + super(memory); + read(); + } + + @Override + protected List getFieldOrder() { + return FIELDS; } /** * Name of the key. @@ -75,19 +87,20 @@ public String getName() { return Native.toString(Name); } - + + @Override public void read() { super.read(); Name = new char[NameLength / 2]; - readField("Name"); + readField("Name"); } } - + /** - * The KEY_INFORMATION_CLASS enumeration type represents + * The KEY_INFORMATION_CLASS enumeration type represents * the type of information to supply about a registry key. */ - public abstract class KEY_INFORMATION_CLASS { + public abstract class KEY_INFORMATION_CLASS { public static final int KeyBasicInformation = 0; public static final int KeyNodeInformation = 1; public static final int KeyFullInformation = 2; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Wevtapi.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Wevtapi.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Wevtapi.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Wevtapi.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,713 @@ +/* Copyright (c) 2016 Minoru Sakamoto, 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.Callback; +import com.sun.jna.Native; +import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.Winevt.EVT_HANDLE; +import com.sun.jna.platform.win32.Winevt.EVT_VARIANT; +import com.sun.jna.ptr.IntByReference; +import com.sun.jna.win32.StdCallLibrary; +import com.sun.jna.win32.W32APIOptions; + +/** + * wevtapi.dll Interface + * + * @author Minoru Sakamoto + */ +public interface Wevtapi extends StdCallLibrary { + Wevtapi INSTANCE = (Wevtapi) Native.loadLibrary("wevtapi", Wevtapi.class, W32APIOptions.UNICODE_OPTIONS); + + /** + * Establishes a connection to a remote computer that you can use when calling the other Windows Event Log functions. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385462(v=vs.85).aspx + * + * @param LoginClass [in] The connection method to use to connect to the remote computer. For possible values, + * see the {@link Winevt.EVT_LOGIN_CLASS} enumeration. + * @param Login [in] A EVT_RPC_LOGIN structure that identifies the remote computer that you want to connect + * to, the user's credentials, and the type of authentication to use when connecting. + * @param Timeout [in] Reserved. Must be zero. + * @param Flags [in]Reserved. Must be zero. + * @return If successful, the function returns a session handle that you can use to access event log information + * on the remote computer; otherwise, NULL. If NULL, call {@link Kernel32#GetLastError} function to get + * the error code. + */ + EVT_HANDLE EvtOpenSession(int LoginClass, Winevt.EVT_RPC_LOGIN Login, int Timeout, int Flags); + + /** + * Closes an open handle. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385344(v=vs.85).aspx + * + * @param Object [in] An open event handle to close. + * @return True The function succeeded, False The function failed. To get the error code, + * call the {@link Kernel32#GetLastError} function. + */ + boolean EvtClose(EVT_HANDLE Object); + + /** + * Cancels all pending operations on a handle. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385335(v=vs.85).aspx + * + * @param Object The handle whose operation you want to cancel. You can cancel the following operations: + *
      + *
    • {@link Wevtapi#EvtClearLog}
    • + *
    • {@link Wevtapi#EvtExportLog}
    • + *
    • {@link Wevtapi#EvtNext}
    • + *
    • {@link Wevtapi#EvtQuery}
    • + *
    • {@link Wevtapi#EvtSeek}
    • + *
    • {@link Wevtapi#EvtSubscribe}
    • + *
    + * To cancel the {@link Wevtapi#EvtClearLog}, {@link Wevtapi#EvtExportLog}, {@link Wevtapi#EvtQuery}, + * and EvtSubscribe operations, you must pass the session handle. To specify the default + * session (local session), set this parameter to NULL. + * @return True The function succeeded, False The function failed. To get the error code, call + * the {@link Kernel32#GetLastError} function. + */ + boolean EvtCancel(EVT_HANDLE Object); + + /** + * Gets a text message that contains the extended error information for the current error. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385380(v=vs.85).aspx + * + * @param BufferSize [in] The size of the Buffer buffer, in characters. + * @param Buffer [in] A caller-allocated string buffer that will receive the extended error information. + * You can set this parameter to NULL to determine the required buffer size. + * @param BufferUsed [out] The size, in characters, of the caller-allocated buffer that the function used or + * the required buffer size if the function fails with ERROR_INSUFFICIENT_BUFFER. + * @return The return value is ERROR_SUCCESS if the call succeeded; otherwise, a Win32 error code. + */ + int EvtGetExtendedStatus(int BufferSize, char[] Buffer, IntByReference BufferUsed); + + /** + * Runs a query to retrieve events from a channel or log file that match the specified query criteria. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385466(v=vs.85).aspx + * + * @param Session [in] A remote session handle that the {@link Wevtapi#EvtOpenSession} function returns. + * Set to NULL to query for events on the local computer. + * @param Path [in] The name of the channel or the full path to a log file that contains the events that + * you want to query. You can specify an .evt, .evtx, or.etl log file. The path is required + * if the Query parameter contains an XPath query; the path is ignored if the Query parameter + * contains a structured XML query and the query specifies the path. + * @param Query [in] A query that specifies the types of events that you want to retrieve. You can specify + * an XPath 1.0 query or structured XML query. If your XPath contains more than 20 expressions, + * use a structured XML query. To receive all events, set this parameter to NULL or "*". + * @param Flags [in] One or more flags that specify the order that you want to receive the events and + * whether you are querying against a channel or log file. For possible values, + * see the {@link Winevt.EVT_QUERY_FLAGS} enumeration. + * @return A handle to the query results if successful; otherwise, NULL. If the function returns NULL, + * call the {@link Kernel32#GetLastError} function to get the error code. + */ + EVT_HANDLE EvtQuery(EVT_HANDLE Session, String Path, String Query, int Flags); + + /** + * Gets the next event from the query or subscription results. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385405(v=vs.85).aspx + * + * @param ResultSet [in] The handle to a query or subscription result set that + * the {@link Wevtapi#EvtQuery} function or the {@link Wevtapi#EvtSubscribe} function returns. + * @param EventArraySize [in] The number of elements in the EventArray array. The function will try to retrieve + * this number of elements from the result set. + * @param EventArray [in] A pointer to an array of handles that will be set to the handles to the events from + * the result set. + * @param Timeout [in] The number of milliseconds that you are willing to wait for a result. + * Set to INFINITE to indicate no time-out value. If the time-out expires, the last error is + * set to ERROR_TIMEOUT. + * @param Flags [in] Reserved. Must be zero. + * @param Returned [out] The number of handles in the array that are set. + * @return True The function succeeded, False The function failed. To get the error code, call + * the {@link Kernel32#GetLastError} function. + */ + boolean EvtNext(EVT_HANDLE ResultSet, int EventArraySize, EVT_HANDLE[] EventArray, int Timeout, int Flags, + IntByReference Returned); + + /** + * Seeks to a specific event in a query result set. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385481(v=vs.85).aspx + * + * @param ResultSet [in] The handle to a query result set that + * the {@link Wevtapi#EvtQuery} function returns. + * @param Position [in] The zero-based offset to an event in the result set. The flag that you specify + * in the Flags parameter indicates the beginning relative position in the result set from + * which to seek. For example, you can seek from the beginning of the results or from the end of + * the results. Set to 0 to move to the relative position specified by the flag. + * @param Bookmark [in] A handle to a bookmark that the {@link Wevtapi#EvtCreateBookmark}function returns. + * The bookmark identifies an event in the result set to which you want to seek. + * Set this parameter only if the Flags parameter has the EvtSeekRelativeToBookmark flag set. + * @param Timeout [in] Reserved. Must be zero. + * @param Flags [in] One or more flags that indicate the relative position in the result set from which to seek. + * For possible values, see the {@link Winevt.EVT_SEEK_FLAGS} enumeration. + * @return True The function was successful, False The function failed. To get the error code, call + * the {@link Kernel32#GetLastError} function. + */ + boolean EvtSeek(EVT_HANDLE ResultSet, long Position, EVT_HANDLE Bookmark, int Timeout, int Flags); + + /** + * Creates a subscription that will receive current and future events from a channel or log file + * that match the specified query criteria. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385487(v=vs.85).aspx + * + * @param Session [in] A remote session handle that the {@link Wevtapi#EvtOpenSession} function returns. + * Set to NULL to subscribe to events on the local computer. + * @param SignalEvent [in] The handle to an event object that the service will signal when new events are + * available that match your query criteria. This parameter must be NULL if the Callback + * parameter is not NULL. + * @param ChannelPath [in] The name of the Admin or Operational channel that contains the events that you want to + * subscribe to (you cannot subscribe to Analytic or Debug channels). The path is required + * if the Query parameter contains an XPath query; the path is ignored if the Query parameter + * contains a structured XML query. + * @param Query [in] A query that specifies the types of events that you want the subscription service to + * return. You can specify an XPath 1.0 query or structured XML query. If your XPath contains + * more than 20 expressions, use a structured XML query. To receive all events, set this + * parameter to NULL or "*". + * @param Bookmark [in] A handle to a bookmark that identifies the starting point for the subscription. To get + * a bookmark handle, call the {@link Wevtapi#EvtCreateBookmark} function. You must set + * this parameter if the Flags parameter contains the EvtSubscribeStartAfterBookmark flag; + * otherwise, NULL. + * @param Context [in] A caller-defined context value that the subscription service will pass to the specified + * callback each time it delivers an event. + * @param Callback [in] Pointer to your EVT_SUBSCRIBE_CALLBACK callback function that will receive + * the subscription events. This parameter must be NULL if the SignalEvent parameter is not NULL. + * @param Flags [in] One or more flags that specify when to start subscribing to events. For example, if you + * specify {@link Winevt.EVT_SUBSCRIBE_FLAGS#EvtSubscribeStartAtOldestRecord}, the service will + * retrieve all current and future events that match your query criteria; however, if you specify + * {@link Winevt.EVT_SUBSCRIBE_FLAGS#EvtSubscribeToFutureEvents}, the service returns only + * future events that match your query criteria. For possible values,see + * the {@link Winevt.EVT_SUBSCRIBE_FLAGS} enumeration. + * @return A handle to the subscription if successful; otherwise, NULL. If the function returns NULL, + * call the {@link Kernel32#GetLastError} function to get the error code. + * You must call the EvtClose function with the subscription handle when done. + */ + EVT_HANDLE EvtSubscribe(EVT_HANDLE Session, EVT_HANDLE SignalEvent, String ChannelPath, String Query, EVT_HANDLE Bookmark, + Pointer Context, Callback Callback, int Flags); + + /** + * Creates a context that specifies the information in the event that you want to render. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385352(v=vs.85).aspx + * + * @param ValuePathsCount [in] The number of XPath expressions in the ValuePaths parameter. + * @param ValuePaths [in] An array of XPath expressions that uniquely identify a node or attribute in + * the event that you want to render. The expressions must not contain the OR or AND operator. + * Set to NULL if the {@link Winevt.EVT_RENDER_CONTEXT_FLAGS#EvtRenderContextValues} context + * flag is not set in the Flags parameter. + * @param Flags [in] One or more flags that identify the information in the event that you want to render. + * For example, the system information, user information, or specific values. + * For possible values, see the {@link Winevt.EVT_RENDER_CONTEXT_FLAGS} enumeration. + * @return A context handle that you use when calling the {@link Wevtapi#EvtRender}function to render the contents + * of an event; otherwise, NULL. If NULL, call the {@link Kernel32#GetLastError} function to get the error code. + */ + EVT_HANDLE EvtCreateRenderContext(int ValuePathsCount, String[] ValuePaths, int Flags); + + /** + * Renders an XML fragment based on the rendering context that you specify. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385471(v=vs.85).aspx + * + * @param Context [in] A handle to the rendering context that the {@link Wevtapi#EvtCreateRenderContext} + * function returns. This parameter must be set to NULL if the Flags parameter is set to + * {@link Winevt.EVT_RENDER_FLAGS#EvtRenderEventXml} or + * {@link Winevt.EVT_RENDER_FLAGS#EvtRenderBookmark}. + * @param Fragment [in] A handle to an event or to a bookmark. Set this parameter to a bookmark handle + * if the Flags parameter is set to {@link Winevt.EVT_RENDER_FLAGS#EvtRenderEventXml}; + * otherwise, set to an event handle. + * @param Flags [in] A flag that identifies what to render. For example, the entire event or specific + * properties of the event. For possible values,see the {@link Winevt.EVT_RENDER_FLAGS} + * enumeration. + * @param BufferSize [in] The size of the Buffer buffer, in bytes. + * @param Buffer [in] A caller-allocated buffer that will receive the rendered output. The contents is + * a null-terminated Unicode string if the Flags parameter is set to + * {@link Winevt.EVT_RENDER_FLAGS#EvtRenderEventXml} or + * {@link Winevt.EVT_RENDER_FLAGS#EvtRenderBookmark}. Otherwise, if Flags is set to + * {@link Winevt.EVT_RENDER_FLAGS#EvtRenderEventValues}, the buffer + * contains an array of EVT_VARIANT structures; one for each property specified by + * the rendering context. The PropertyCount parameter contains the number of elements + * in the array. + * @param BufferUsed [out] The size, in bytes, of the caller-allocated buffer that the function used or + * the required buffer size if the function fails with ERROR_INSUFFICIENT_BUFFER. + * @param PropertyCount [out] The number of the properties in the Buffer parameter if the Flags parameter is set + * to {@link Winevt.EVT_RENDER_FLAGS#EvtRenderEventValues}; otherwise, zero. + * @return True The function was successful, False The function failed. To get the error code, call + * the {@link Kernel32#GetLastError} function. + */ + boolean EvtRender(EVT_HANDLE Context, EVT_HANDLE Fragment, int Flags, int BufferSize, Pointer Buffer, + IntByReference BufferUsed, IntByReference PropertyCount); + + /** + * Formats a message string. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385359(v=vs.85).aspx + * + * @param PublisherMetadata [in] A handle to the provider's metadata that + * the {@link Wevtapi#EvtOpenPublisherMetadata} function returns. The handle acts as + * a formatting context for the event or message identifier. + *

    + * You can set this parameter to NULL if the Windows Event Collector service forwarded + * the event. Forwarded events include a RenderingInfo section that contains the rendered + * message strings. You can also set this parameter to NULL if the event property that + * you are formatting is defined in the Winmeta.xml file (for example, if level is set + * to win:Error). In the latter case, the service uses the Winmeta provider as + * the formatting context and will format only those message strings that you reference + * in your event that are defined in the Winmeta.xml file. + * @param Event [in] A handle to an event. The Flags parameter specifies the message string in + * the event that you want to format. This parameter must be NULL if the Flags parameter + * is set to EvtFormatMessageId. + * @param MessageId [in] The resource identifier of the message string that you want to format. + * To get the resource identifier for a message string, call + * the {@link Wevtapi#EvtGetPublisherMetadataProperty} function. Set this parameter only + * if the Flags parameter is set to EvtFormatMessageId. + * @param ValueCount [in] The number of values in the Values parameter. + * @param Values [in] An array of insertion values to use when formatting the event's message string. + * Typically, you set this parameter to NULL and the function gets the insertion values + * from the event data itself. You would use this parameter to override the default + * behavior and supply the insertion values to use. For example, you might use this + * parameter if you wanted to resolve a SID to a principal name before inserting the value. + *

    + * To override the insertion values, the Flags parameter must be set to + * {@link Winevt.EVT_FORMAT_MESSAGE_FLAGS#EvtFormatMessageEvent}, + * {@link Winevt.EVT_FORMAT_MESSAGE_FLAGS#EvtFormatMessageXml}, or + * {@link Winevt.EVT_FORMAT_MESSAGE_FLAGS#EvtFormatMessageId}, If Flags is set to + * {@link Winevt.EVT_FORMAT_MESSAGE_FLAGS#EvtFormatMessageId}, the resource identifier + * must identify the event's message string. + * @param Flags [in] A flag that specifies the message string in the event to format. For possible + * values, see the {@link Winevt.EVT_FORMAT_MESSAGE_FLAGS} enumeration. + * @param BufferSize [in] The size of the Buffer buffer, in characters. + * @param Buffer [in] A caller-allocated buffer that will receive the formatted message string. + * You can set this parameter to NULL to determine the required buffer size. + * @param BufferUsed [out] The size, in characters of the caller-allocated buffer that the function used + * or the required buffer size if the function fails with ERROR_INSUFFICIENT_BUFFER. + * @return True The function was successful, False The function failed. To get the error code, call + * the {@link Kernel32#GetLastError} function. + */ + boolean EvtFormatMessage(EVT_HANDLE PublisherMetadata, EVT_HANDLE Event, int MessageId, int ValueCount, EVT_VARIANT[] Values, + int Flags, int BufferSize, char[] Buffer, IntByReference BufferUsed); + + /** + * Gets a handle to a channel or log file that you can then use to get information about the channel or log file. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385447(v=vs.85).aspx + * + * @param Session [in] A remote session handle that the {@link Wevtapi#EvtOpenSession} function returns. + * Set to NULL to open a channel or log on the local computer. + * @param Path [in] The name of the channel or the full path to the exported log file. + * @param Flags [in] A flag that determines whether the Path parameter points to a log file or channel. + * For possible values, see the {@link Winevt.EVT_OPEN_LOG_FLAGS} enumeration. + * @return If successful, the function returns a handle to the file or channel; + * otherwise, NULL. If NULL, call {@link Kernel32#GetLastError} function to get the error code. + */ + EVT_HANDLE EvtOpenLog(EVT_HANDLE Session, String Path, int Flags); + + /** + * Gets information about a channel or log file. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385385(v=vs.85).aspx + * + * @param Log [in] A handle to the channel or log file that the {@link Wevtapi#EvtOpenLog} + * function returns. + * @param PropertyId [in] The identifier of the property to retrieve. For a list of property + * identifiers, see the {@link Winevt.EVT_LOG_PROPERTY_ID} enumeration. + * @param PropertyValueBufferSize [in] The size of the PropertyValueBuffer buffer, in bytes. + * @param PropertyValueBuffer [in] A caller-allocated buffer that will receive the property value. The buffer + * contains an EVT_VARIANT object. You can set this parameter to NULL to determine + * the required buffer size. + * @param PropertyValueBufferUsed [out] The size, in bytes, of the caller-allocated buffer that + * the function used or the required buffer size if the function fails + * with ERROR_INSUFFICIENT_BUFFER. + * @return True The function was successful, False The function failed. To get the error code, call + * the {@link Kernel32#GetLastError} function. + */ + boolean EvtGetLogInfo(EVT_HANDLE Log, int PropertyId, int PropertyValueBufferSize, Pointer PropertyValueBuffer, + IntByReference PropertyValueBufferUsed); + + /** + * Removes all events from the specified channel and writes them to the target log file. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385340(v=vs.85).aspx + * + * @param Session [in, optional] A remote session handle that the {@link Wevtapi#EvtOpenSession} function + * returns. Set to NULL for local channels. + * @param ChannelPath [in] The name of the channel to clear. + * @param TargetFilePath [in, optional] The full path to the target log file that will receive the events. + * Set to NULL to clear the log file and not save the events. + * @param Flags [in] Reserved. Must be zero. + * @return True The function was successful, False The function failed. To get the error code, call + * the {@link Kernel32#GetLastError} function. + */ + boolean EvtClearLog(EVT_HANDLE Session, String ChannelPath, String TargetFilePath, int Flags); + + /** + * Copies events from the specified channel or log file and writes them to the target log file. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385355(v=vs.85).aspx + * + * @param Session [in, optional] A remote session handle that the {@link Wevtapi#EvtOpenSession} function + * returns. Set to NULL for local channels. + * @param Path [in] The name of the channel or the full path to a log file that contains the events that + * you want to export. If the Query parameter contains an XPath query, you must specify + * the channel or log file. If the Flags parameter contains + * {@link Winevt.EVT_EXPORTLOG_FLAGS#EvtExportLogFilePath}, you must specify the log file. + * If the Query parameter contains a structured XML query, the channel or path that you + * specify here must match the channel or path in the query. If the Flags parameter contains + * {@link Winevt.EVT_EXPORTLOG_FLAGS#EvtExportLogChannelPath}, this parameter can be NULL + * if the query is a structured XML query that specifies the channel. + * @param Query [in] A query that specifies the types of events that you want to export. You can specify + * an XPath 1.0 query or structured XML query. If your XPath contains more than 20 expressions, + * use a structured XML query. To export all events, set this parameter to NULL or "*". + * @param TargetFilePath [in] The full path to the target log file that will receive the events. + * The target log file must not exist. + * @param Flags [in] Flags that indicate whether the events come from a channel or log file. For possible + * values, see the {@link Winevt.EVT_EXPORTLOG_FLAGS#EvtExportLogChannelPath} enumeration. + * @return True The function was successful, False The function failed. To get the error code, call + * the {@link Kernel32#GetLastError} function. + */ + boolean EvtExportLog(EVT_HANDLE Session, String Path, String Query, String TargetFilePath, int Flags); + + /** + * Adds localized strings to the events in the specified log file. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385232(v=vs.85).aspx + * + * @param Session [in] A remote session handle that the {@link Wevtapi#EvtOpenSession} function returns. + * Set to NULL for local channels. + * @param LogFilePath [in] The full path to the exported log file that contains the events to localize. + * @param Locale [in] The locale to use to localize the strings that the service adds to the events in + * the log file. If zero, the function uses the calling thread's locale. If the provider's + * resources does not contain the locale, the string is empty. + * @param Flags [in] Reserved. Must be zero. + * @return True The function succeeded, False The function failed. To get the error code, + * call the {@link Kernel32#GetLastError} function. + */ + boolean EvtArchiveExportedLog(EVT_HANDLE Session, String LogFilePath, int Locale, int Flags); + + /** + * Gets a handle that you use to enumerate the list of channels that are registered on the computer. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385437(v=vs.85).aspx + * + * @param Session [in] A remote session handle that the {@link Wevtapi#EvtOpenSession} function returns. + * Set to NULL to enumerate the channels on the local computer. + * @param Flags [in] Reserved. Must be zero. + * @return If successful, the function returns a handle to the list of channel names that are registered on + * the computer; otherwise, NULL. If NULL, call {@link Kernel32#GetLastError} function to get the error code. + */ + EVT_HANDLE EvtOpenChannelEnum(EVT_HANDLE Session, int Flags); + + /** + * Gets a channel name from the enumerator. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385412(v=vs.85).aspx + * + * @param ChannelEnum [in] A handle to the enumerator that the {@link Wevtapi#EvtOpenChannelEnum} + * function returns. + * @param ChannelPathBufferSize [in] The size of the ChannelPathBuffer buffer, in characters. + * @param ChannelPathBuffer [in] A caller-allocated buffer that will receive the name of the channel. + * You can set this parameter to NULL to determine the required buffer size. + * @param ChannelPathBufferUsed [out] The size, in characters, of the caller-allocated buffer that the function + * used or the required buffer size if the function fails with ERROR_INSUFFICIENT_BUFFER. + * @return True The function succeeded, False The function failed. To get the error code, + * call the {@link Kernel32#GetLastError} function. + */ + boolean EvtNextChannelPath(EVT_HANDLE ChannelEnum, int ChannelPathBufferSize, char[] ChannelPathBuffer, + IntByReference ChannelPathBufferUsed); + + /** + * Gets a handle that you use to read or modify a channel's configuration property. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385430(v=vs.85).aspx + * + * @param Session [in] A remote session handle that the {@link Wevtapi#EvtOpenSession} function returns. + * Set to NULL to access a channel on the local computer. + * @param ChannelPath [in] The name of the channel to access. + * @param Flags [in] Reserved. Must be zero. + * @return If successful, the function returns a handle to the channel's configuration; + * otherwise, NULL. If NULL, call GetLastError function to get the error code. + */ + EVT_HANDLE EvtOpenChannelConfig(EVT_HANDLE Session, String ChannelPath, int Flags); + + /** + * Saves the changes made to a channel's configuration. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385477(v=vs.85).aspx + * + * @param ChannelConfig [in] A handle to the channel's configuration properties that + * the {@link Wevtapi#EvtOpenChannelConfig} function returns. + * @param Flags [in] Reserved. Must be zero. + * @return True The function succeeded, False The function failed. To get the error code, + * call the {@link Kernel32#GetLastError} function. + */ + boolean EvtSaveChannelConfig(EVT_HANDLE ChannelConfig, int Flags); + + /** + * Sets the specified configuration property of a channel. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385484(v=vs.85).aspx + * + * @param ChannelConfig [in] A handle to the channel's configuration properties that + * the {@link Wevtapi#EvtOpenChannelConfig} function returns. + * @param PropertyId [in] The identifier of the channel property to set. For a list of property identifiers, + * see the {@link Winevt.EVT_CHANNEL_CONFIG_PROPERTY_ID} enumeration. + * @param Flags [in] Reserved. Must be zero. + * @param PropertyValue [in] The property value to set. + * A caller-allocated buffer that contains the new configuration property value. + * The buffer contains an EVT_VARIANT object. Be sure to set the configuration value and + * variant type. + * @return True The function succeeded, False The function failed. To get the error code, + * call the {@link Kernel32#GetLastError} function. + */ + boolean EvtSetChannelConfigProperty(EVT_HANDLE ChannelConfig, int PropertyId, int Flags, EVT_VARIANT PropertyValue); + + /** + * Gets the specified channel configuration property. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385362(v=vs.85).aspx + * + * @param ChannelConfig [in] A handle to the channel's configuration properties that + * the {@link Wevtapi#EvtOpenChannelConfig} function returns. + * @param PropertyId [in] The identifier of the channel property to retrieve. For a list of property + * identifiers, see the {@link Winevt.EVT_CHANNEL_CONFIG_PROPERTY_ID} enumeration. + * @param Flags [in] Reserved. Must be zero. + * @param PropertyValueBufferSize [in] The size of the PropertyValueBuffer buffer, in bytes. + * @param PropertyValueBuffer [in] A caller-allocated buffer that will receive the configuration property. + * The buffer contains an EVT_VARIANT object. You can set this parameter to NULL + * to determine the required buffer size. + * @param PropertyValueBufferUsed [out] The size, in bytes, of the caller-allocated buffer that the function + * used or the required buffer size if the function fails with ERROR_INSUFFICIENT_BUFFER. + * @return True The function succeeded, False The function failed. To get the error code, + * call the {@link Kernel32#GetLastError} function. + */ + boolean EvtGetChannelConfigProperty(EVT_HANDLE ChannelConfig, int PropertyId, int Flags, int PropertyValueBufferSize, + Pointer PropertyValueBuffer, IntByReference PropertyValueBufferUsed); + + /** + * Gets a handle that you use to enumerate the list of registered providers on the computer. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385451(v=vs.85).aspx + * + * @param Session [in] A remote session handle that the {@link Wevtapi#EvtOpenSession} function returns. + * Set to NULL to enumerate the registered providers on the local computer. + * @param Flags [in] Reserved. Must be zero. + * @return If successful, the function returns a handle to the list of registered providers; + * otherwise, NULL. If NULL, call {@link Kernel32#GetLastError} function to get the error code. + */ + EVT_HANDLE EvtOpenPublisherEnum(EVT_HANDLE Session, int Flags); + + /** + * Gets the identifier of a provider from the enumerator. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385425(v=vs.85).aspx + * + * @param PublisherEnum [in] A handle to the registered providers enumerator that + * the {@link Wevtapi#EvtOpenPublisherEnum} function returns. + * @param PublisherIdBufferSize [in] The size of the PublisherIdBuffer buffer, in characters. + * @param PublisherIdBuffer [in] A caller-allocated buffer that will receive the name of the registered + * provider. You can set this parameter to NULL to determine the required buffer size. + * @param PublisherIdBufferUsed [out] The size, in characters, of the caller-allocated buffer that the function + * used or the required buffer size if the function fails with ERROR_INSUFFICIENT_BUFFER. + * @return If successful, the function returns a handle to the list of registered providers; + * otherwise, NULL. If NULL, call {@link Kernel32#GetLastError} function to get the error code. + */ + boolean EvtNextPublisherId(EVT_HANDLE PublisherEnum, int PublisherIdBufferSize, char[] PublisherIdBuffer, + IntByReference PublisherIdBufferUsed); + + /** + * Gets a handle that you use to read the specified provider's metadata. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385458(v=vs.85).aspx + * + * @param EvtHandleSession [in, optional] A remote session handle that the {@link Wevtapi#EvtOpenSession} + * function returns. Set to NULL to get the metadata for a provider on the local computer. + * @param PublisherIdentity [in] The name of the provider. To enumerate the names of the providers registered on + * the computer, call the {@link Wevtapi#EvtOpenPublisherEnum} function. + * @param LogFilePath [in, optional] The full path to an archived log file that contains the events that + * the provider logged. An archived log file also contains the provider's metadata. Use + * this parameter when the provider is not registered on the local computer. Set to NULL + * when reading the metadata from a registered provider.. + * @param Locale [in] The locale identifier to use when accessing the localized metadata from + * the provider. To create the locale identifier, use the MAKELCID macro. Set to 0 to use + * the locale identifier of the calling thread. + * @param Flags [in] Reserved. Must be zero. + * @return If successful, the function returns a handle to the provider's metadata; + * otherwise, NULL. If NULL, call {@link Kernel32#GetLastError} function to get the error code. + */ + EVT_HANDLE EvtOpenPublisherMetadata(EVT_HANDLE EvtHandleSession, String PublisherIdentity, String LogFilePath, int Locale, int Flags); + + /** + * Gets the specified provider metadata property. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385399(v=vs.85).aspx + * + * @param PublisherMetadata [in] A handle to the metadata that + * the {@link Wevtapi#EvtOpenPublisherMetadata} function returns. + * @param PropertyId [in] The identifier of the metadata property to retrieve. + * For a list of property identifiers, see + * the {@link Winevt.EVT_PUBLISHER_METADATA_PROPERTY_ID} enumeration. + * @param Flags [in] Reserved. Must be zero. + * @param PublisherMetadataPropertyBufferSize [in] The size of the PublisherMetadataPropertyBuffer buffer, + * in bytes. + * @param PublisherMetadataPropertyBuffer [in] A caller-allocated buffer that will receive the metadata + * property. The buffer contains an EVT_VARIANT object. You can set this + * parameter to NULL to determine the required buffer size. + * @param PublisherMetadataPropertyBufferUsed [out] The size, in bytes, of the caller-allocated buffer that + * the function used or the required buffer size if the function fails + * with ERROR_INSUFFICIENT_BUFFER. + * @return True The function succeeded, False The function failed. To get the error code, + * call the {@link Kernel32#GetLastError} function. + */ + boolean EvtGetPublisherMetadataProperty(EVT_HANDLE PublisherMetadata, int PropertyId, int Flags, + int PublisherMetadataPropertyBufferSize, + Pointer PublisherMetadataPropertyBuffer, + IntByReference PublisherMetadataPropertyBufferUsed); + + /** + * Gets a handle that you use to enumerate the list of events that the provider defines. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385446(v=vs.85).aspx + * + * @param PublisherMetadata [in] A handle to the provider's metadata that + * the {@link Wevtapi#EvtOpenPublisherMetadata} function returns. + * @param Flags [in] Reserved. Must be zero. + * @return If successful, the function returns a handle to the list of events that the provider defines; + * otherwise, NULL. If NULL, call {@link Kernel32#GetLastError} function to get the error code. + */ + EVT_HANDLE EvtOpenEventMetadataEnum(EVT_HANDLE PublisherMetadata, int Flags); + + /** + * Gets an event definition from the enumerator. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385419(v=vs.85).asp + * + * @param EventMetadataEnum [in] A handle to the event definition enumerator that + * the {@link Wevtapi#EvtOpenEventMetadataEnum} function returns. + * @param Flags [in] Reserved. Must be zero. + * @return If successful, the function returns a handle to the event's metadata; + * otherwise, NULL. If NULL, call {@link Kernel32#GetLastError} function to get the error code. + */ + EVT_HANDLE EvtNextEventMetadata(EVT_HANDLE EventMetadataEnum, int Flags); + + /** + * Gets the specified event metadata property. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385376(v=vs.85).aspx + * + * @param EventMetadata [in] A handle to the event metadata that + * the {@link Wevtapi#EvtNextEventMetadata} function returns. + * @param PropertyId [in] The identifier of the metadata property to retrieve. For a list of + * property identifiers, see + * the {@link Winevt.EVT_EVENT_METADATA_PROPERTY_ID} enumeration. + * @param Flags [in] Reserved. Must be zero. + * @param EventMetadataPropertyBufferSize [in] The size of the EventMetadataPropertyBuffer buffer, in bytes. + * @param Buffer [in] A caller-allocated buffer that will receive the metadata property. + * The buffer contains an EVT_VARIANT object. You can set this parameter to + * NULL to determine the required buffer size. + * @param BufferUsed [out] The size, in bytes, of the caller-allocated buffer that + * the function used or the required buffer size if the function fails + * with ERROR_INSUFFICIENT_BUFFER. + * @return True The function succeeded, False The function failed. To get the error code, + * call the {@link Kernel32#GetLastError} function. + */ + boolean EvtGetEventMetadataProperty(EVT_HANDLE EventMetadata, int PropertyId, int Flags, + int EventMetadataPropertyBufferSize, Pointer Buffer, IntByReference BufferUsed); + + /** + * Gets the number of elements in the array of objects. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385394(v=vs.85).aspx + * + * @param ObjectArray [in] A handle to an array of objects that + * the {@link Wevtapi#EvtGetPublisherMetadataProperty} function returns. + * @param ObjectArraySize [out] The number of elements in the array. + * @return True The function succeeded, False The function failed. To get the error code, + * call the {@link Kernel32#GetLastError} function. + */ + boolean EvtGetObjectArraySize(Pointer ObjectArray, IntByReference ObjectArraySize); + + /** + * Gets a provider metadata property from the specified object in the array. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385389(v=vs.85).aspx + * + * @param ObjectArray [in] A handle to an array of objects that + * the {@link Wevtapi#EvtGetPublisherMetadataProperty} function returns. + * @param PropertyId [in] The property identifier of the metadata property that you want to get from + * the specified object. For possible values, see the Remarks section of + * {@link Winevt.EVT_PUBLISHER_METADATA_PROPERTY_ID}. + * @param ArrayIndex [in] The zero-based index of the object in the array. + * @param Flags [in] Reserved. Must be zero. + * @param PropertyValueBufferSize [in] The size of the PropertyValueBuffer buffer, in bytes. + * @param PropertyValueBuffer [in] A caller-allocated buffer that will receive the metadata property. + * The buffer contains an EVT_VARIANT object. You can set this parameter to NULL + * to determine the required buffer size. + * @param PropertyValueBufferUsed [in] The size, in bytes, of the caller-allocated buffer that the function used + * or the required buffer size if the function fails with ERROR_INSUFFICIENT_BUFFER. + * @return True The function succeeded, False The function failed. To get the error code, + * call the {@link Kernel32#GetLastError} function. + */ + boolean EvtGetObjectArrayProperty(Pointer ObjectArray, int PropertyId, int ArrayIndex, int Flags, + int PropertyValueBufferSize, Pointer PropertyValueBuffer, + IntByReference PropertyValueBufferUsed); + + /** + * Gets information about a query that you ran that identifies the list of channels or log files that the query + * attempted to access. The function also gets a list of return codes that indicates the success or failure of each + * access. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa820606(v=vs.85).aspx + * + * @param QueryOrSubscription [in] A handle to the query that the {@link Wevtapi#EvtQuery} or + * {@link Wevtapi#EvtSubscribe} function returns. + * @param PropertyId [in] The identifier of the query information to retrieve. For a list of + * identifiers, see the {@link Winevt.EVT_QUERY_PROPERTY_ID} enumeration. + * @param PropertyValueBufferSize [in] The size of the PropertyValueBuffer buffer, in bytes. + * @param PropertyValueBuffer [in] A caller-allocated buffer that will receive the query information. + * The buffer contains an EVT_VARIANT object. You can set this parameter to NULL to + * determine the required buffer size. + * @param PropertyValueBufferUsed [out] The size, in bytes, of the caller-allocated buffer that the + * function used or the required buffer size if the function fails + * with ERROR_INSUFFICIENT_BUFFER. + * @return True The function succeeded, False The function failed. To get the error code, + * call the {@link Kernel32#GetLastError} function. + */ + boolean EvtGetQueryInfo(EVT_HANDLE QueryOrSubscription, int PropertyId, int PropertyValueBufferSize, + Pointer PropertyValueBuffer, IntByReference PropertyValueBufferUsed); + + /** + * Creates a bookmark that identifies an event in a channel. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385348(v=vs.85).aspx + * + * @param BookmarkXml [in, optional] An XML string that contains the bookmark or NULL if creating a bookmark. + * @return A handle to the bookmark if the call succeeds; + * otherwise, NULL. If NULL, call the {@link Kernel32#GetLastError} function to get the error code. + */ + EVT_HANDLE EvtCreateBookmark(String BookmarkXml); + + /** + * Updates the bookmark with information that identifies the specified event. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385489(v=vs.85).aspx + * + * @param Bookmark [in] The handle to the bookmark to be updated. The {@link Wevtapi#EvtCreateBookmark} function + * returns this handle. + * @param Event [in] The handle to the event to bookmark. + * @return True The function succeeded, False The function failed. To get the error code, + * call the {@link Kernel32#GetLastError} function. + */ + boolean EvtUpdateBookmark(EVT_HANDLE Bookmark, EVT_HANDLE Event); + + /** + * Gets information that identifies the structured XML query that selected the event and the channel or log file + * that contained the event. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385372(v=vs.85).aspx + * + * @param Event [in] A handle to an event for which you want to retrieve information. + * @param PropertyId [in] A flag that identifies the information to retrieve. For example, the query + * identifier or the path. For possible values, + * see the {@link Winevt.EVT_EVENT_PROPERTY_ID} enumeration. + * @param PropertyValueBufferSize [in] The size of the PropertyValueBuffer buffer, in bytes. + * @param PropertyValueBuffer [in] A caller-allocated buffer that will receive the information. The buffer + * contains an EVT_VARIANT object. You can set this parameter to NULL to determine + * the required buffer size. + * @param PropertyValueBufferUsed [in] The size, in bytes, of the caller-allocated buffer that the function used + * or the required buffer size if the function fails with ERROR_INSUFFICIENT_BUFFER. + * @return True The function succeeded, False The function failed. To get the error code, + * call the {@link Kernel32#GetLastError} function. + */ + boolean EvtGetEventInfo(EVT_HANDLE Event, int PropertyId, int PropertyValueBufferSize, Pointer PropertyValueBuffer, + IntByReference PropertyValueBufferUsed); + +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/WevtapiUtil.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/WevtapiUtil.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/WevtapiUtil.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/WevtapiUtil.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,236 @@ +/* Copyright (c) 2016 Minoru Sakamoto, 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.Memory; +import com.sun.jna.Native; +import com.sun.jna.platform.win32.Winevt.EVT_HANDLE; +import com.sun.jna.platform.win32.Winevt.EVT_VARIANT; +import com.sun.jna.ptr.IntByReference; + +/** + * Wevtapi Utilities Class + * + * @author Minoru Sakamoto + */ +public abstract class WevtapiUtil { + + /** + * Gets a text message that contains the extended error information for the current error. + * + * @return error information text + */ + public static String EvtGetExtendedStatus() { + int errorCode; + IntByReference buffUsed = new IntByReference(); + errorCode = Wevtapi.INSTANCE.EvtGetExtendedStatus(0, null, buffUsed); + if (errorCode != WinError.ERROR_SUCCESS && errorCode != WinError.ERROR_INSUFFICIENT_BUFFER) { + throw new Win32Exception(errorCode); + } + if (buffUsed.getValue() == 0) { + return ""; + } + char[] mem = new char[buffUsed.getValue()]; + errorCode = Wevtapi.INSTANCE.EvtGetExtendedStatus(mem.length, mem, buffUsed); + if (errorCode != WinError.ERROR_SUCCESS) { + throw new Win32Exception(errorCode); + } + return Native.toString(mem); + } + + + /** + * Renders an XML fragment based on the rendering context that you specify. + * + * @param context [in] A handle to the rendering context that the {@link Wevtapi#EvtCreateRenderContext} + * function returns. This parameter must be set to NULL if the Flags parameter is set to + * {@link Winevt.EVT_RENDER_FLAGS#EvtRenderEventXml} or + * {@link Winevt.EVT_RENDER_FLAGS#EvtRenderBookmark}. + * @param fragment [in] A handle to an event or to a bookmark. Set this parameter to a bookmark handle + * if the Flags parameter is set to {@link Winevt.EVT_RENDER_FLAGS#EvtRenderEventXml}; + * otherwise, set to an event handle. + * @param flags [in] A flag that identifies what to render. For example, the entire event or specific + * properties of the event. For possible values,see the {@link Winevt.EVT_RENDER_FLAGS} + * enumeration. + * @param propertyCount [out] The number of the properties in the Buffer parameter if the Flags parameter is set + * to {@link Winevt.EVT_RENDER_FLAGS#EvtRenderEventValues}; otherwise, zero. + * @return A caller-allocated buffer that will receive the rendered output. The contents is a null-terminated + * Unicode string if the Flags parameter is set to {@link Winevt.EVT_RENDER_FLAGS#EvtRenderEventXml} or + * {@link Winevt.EVT_RENDER_FLAGS#EvtRenderBookmark}. Otherwise, if Flags is set to {@link Winevt.EVT_RENDER_FLAGS#EvtRenderEventValues}, + * the buffer contains an array of EVT_VARIANT structures; one for each property specified by the rendering context. + * The PropertyCount parameter contains the number of elements in the array. the {@link Kernel32#GetLastError} function. + */ + public static Memory EvtRender(EVT_HANDLE context, EVT_HANDLE fragment, int flags, IntByReference propertyCount) { + boolean result; + IntByReference buffUsed = new IntByReference(); + result = Wevtapi.INSTANCE.EvtRender(context, fragment, flags, 0, null, buffUsed, propertyCount); + int errorCode = Kernel32.INSTANCE.GetLastError(); + if ((!result) && errorCode != Kernel32.ERROR_INSUFFICIENT_BUFFER) { + throw new Win32Exception(errorCode); + } + Memory mem = new Memory(buffUsed.getValue()); + result = Wevtapi.INSTANCE.EvtRender(context, fragment, flags, (int) mem.size(), mem, buffUsed, propertyCount); + if (!result) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + return mem; + } + + /** + * Formats a message string. + * + * @param publisherMetadata [in] A handle to the provider's metadata that + * the {@link Wevtapi#EvtOpenPublisherMetadata} function returns. The handle acts as + * a formatting context for the event or message identifier. + *

    + * You can set this parameter to NULL if the Windows Event Collector service forwarded + * the event. Forwarded events include a RenderingInfo section that contains the rendered + * message strings. You can also set this parameter to NULL if the event property that + * you are formatting is defined in the Winmeta.xml file (for example, if level is set + * to win:Error). In the latter case, the service uses the Winmeta provider as + * the formatting context and will format only those message strings that you reference + * in your event that are defined in the Winmeta.xml file. + * @param event [in] A handle to an event. The Flags parameter specifies the message string in + * the event that you want to format. This parameter must be NULL if the Flags parameter + * is set to EvtFormatMessageId. + * @param messageId [in] The resource identifier of the message string that you want to format. + * To get the resource identifier for a message string, call + * the {@link Wevtapi#EvtGetPublisherMetadataProperty} function. Set this parameter only + * if the Flags parameter is set to EvtFormatMessageId. + * @param valueCount [in] The number of values in the Values parameter. + * @param values [in] An array of insertion values to use when formatting the event's message string. + * Typically, you set this parameter to NULL and the function gets the insertion values + * from the event data itself. You would use this parameter to override the default + * behavior and supply the insertion values to use. For example, you might use this + * parameter if you wanted to resolve a SID to a principal name before inserting the value. + *

    + * To override the insertion values, the Flags parameter must be set to + * {@link Winevt.EVT_FORMAT_MESSAGE_FLAGS#EvtFormatMessageEvent}, + * {@link Winevt.EVT_FORMAT_MESSAGE_FLAGS#EvtFormatMessageXml}, or + * {@link Winevt.EVT_FORMAT_MESSAGE_FLAGS#EvtFormatMessageId}, If Flags is set to + * {@link Winevt.EVT_FORMAT_MESSAGE_FLAGS#EvtFormatMessageId}, the resource identifier + * must identify the event's message string. + * @param flags [in] A flag that specifies the message string in the event to format. For possible + * values, see the {@link Winevt.EVT_FORMAT_MESSAGE_FLAGS} enumeration. + * @return Formatted message string + */ + public static String EvtFormatMessage(EVT_HANDLE publisherMetadata, EVT_HANDLE event, int messageId, int valueCount, + EVT_VARIANT[] values, int flags) { + boolean result; + IntByReference bufferUsed = new IntByReference(); + result = Wevtapi.INSTANCE.EvtFormatMessage(publisherMetadata, event, messageId, valueCount, values, flags, 0, null, bufferUsed); + int errorCode = Kernel32.INSTANCE.GetLastError(); + if ((!result) && errorCode != Kernel32.ERROR_INSUFFICIENT_BUFFER) { + throw new Win32Exception(errorCode); + } + + char[] buffer = new char[bufferUsed.getValue()]; + result = Wevtapi.INSTANCE.EvtFormatMessage(publisherMetadata, event, messageId, valueCount, values, flags, + buffer.length, buffer, bufferUsed); + if (!result) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + return Native.toString(buffer); + } + + /** + * Gets the specified channel configuration property. + * + * @param channelHandle [in] A handle to the channel's configuration properties that + * the {@link Wevtapi#EvtOpenChannelConfig} function returns. + * @param propertyId [in] The identifier of the channel property to retrieve. For a list of property + * identifiers, see the {@link Winevt.EVT_CHANNEL_CONFIG_PROPERTY_ID} enumeration. + * @return EVT_VARIANT(already reading from native memory) + */ + public static EVT_VARIANT EvtGetChannelConfigProperty(EVT_HANDLE channelHandle, int propertyId) { + IntByReference propertyValueBufferUsed = new IntByReference(); + boolean result = Wevtapi.INSTANCE.EvtGetChannelConfigProperty(channelHandle, propertyId, 0, 0, null, propertyValueBufferUsed); + int errorCode = Kernel32.INSTANCE.GetLastError(); + if ((!result) && errorCode != Kernel32.ERROR_INSUFFICIENT_BUFFER) { + throw new Win32Exception(errorCode); + } + + Memory propertyValueBuffer = new Memory(propertyValueBufferUsed.getValue()); + result = Wevtapi.INSTANCE.EvtGetChannelConfigProperty(channelHandle, propertyId, 0, (int) propertyValueBuffer.size(), + propertyValueBuffer, propertyValueBufferUsed); + if (!result) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + EVT_VARIANT resultEvt = new EVT_VARIANT(propertyValueBuffer); + resultEvt.read(); + return resultEvt; + } + + /** + * Gets the identifier of a provider from the enumerator. + * + * @param publisherEnum [in] A handle to the registered providers enumerator that + * the {@link Wevtapi#EvtOpenPublisherEnum} function returns. + * @return The name of the registered provider. + */ + public static String EvtNextPublisherId(EVT_HANDLE publisherEnum) { + IntByReference publisherIdBufferUsed = new IntByReference(); + boolean result = Wevtapi.INSTANCE.EvtNextPublisherId(publisherEnum, 0, null, publisherIdBufferUsed); + int errorCode = Kernel32.INSTANCE.GetLastError(); + if ((!result) && errorCode != Kernel32.ERROR_INSUFFICIENT_BUFFER) { + throw new Win32Exception(errorCode); + } + + char[] publisherIdBuffer = new char[publisherIdBufferUsed.getValue()]; + result = Wevtapi.INSTANCE.EvtNextPublisherId(publisherEnum, publisherIdBuffer.length, publisherIdBuffer, publisherIdBufferUsed); + if (!result) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + return Native.toString(publisherIdBuffer); + } + + /** + * Gets the specified provider metadata property. + * + * @param PublisherMetadata [in] A handle to the metadata that + * the {@link Wevtapi#EvtOpenPublisherMetadata} function returns. + * @param PropertyId [in] The identifier of the metadata property to retrieve. + * For a list of property identifiers, see + * the {@link Winevt.EVT_PUBLISHER_METADATA_PROPERTY_ID} enumeration. + * @param Flags [in] Reserved. Must be zero. + * @return A caller-allocated buffer that will receive the metadata property. The buffer contains an EVT_VARIANT object. + */ + public static Memory EvtGetPublisherMetadataProperty(EVT_HANDLE PublisherMetadata, int PropertyId, int Flags) { + IntByReference publisherMetadataPropertyBufferUsed = new IntByReference(); + boolean result = Wevtapi.INSTANCE.EvtGetPublisherMetadataProperty(PublisherMetadata, PropertyId, Flags, 0, null, + publisherMetadataPropertyBufferUsed); + int errorCode = Kernel32.INSTANCE.GetLastError(); + if ((!result) && errorCode != Kernel32.ERROR_INSUFFICIENT_BUFFER) { + throw new Win32Exception(errorCode); + } + Memory publisherMetadataPropertyBuffer = new Memory(publisherMetadataPropertyBufferUsed.getValue()); + result = Wevtapi.INSTANCE.EvtGetPublisherMetadataProperty(PublisherMetadata, PropertyId, Flags, + (int) publisherMetadataPropertyBuffer.size(), publisherMetadataPropertyBuffer, publisherMetadataPropertyBufferUsed); + if (!result) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + return publisherMetadataPropertyBuffer; + } + +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Win32Exception.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Win32Exception.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Win32Exception.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Win32Exception.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,54 +1,72 @@ /* 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.LastErrorException; import com.sun.jna.platform.win32.WinNT.HRESULT; /** * Win32 exception. * @author dblock[at]dblock[dot]org */ -public class Win32Exception extends RuntimeException { - - private static final long serialVersionUID = 1L; - - private HRESULT _hr; - +public class Win32Exception extends LastErrorException { + + private static final long serialVersionUID = 1L; + + private HRESULT _hr; + /** * Returns the error code of the error. - * @return - * Error code. + * @return HRESULT value */ public HRESULT getHR() { return _hr; } /** - * New Win32 exception from HRESULT. - * @param hr - * HRESULT + * New Win32 exception from an error code, usually obtained from {@code GetLastError.} + * @param code Error code. */ - public Win32Exception(HRESULT hr) { - super(Kernel32Util.formatMessage(hr)); - _hr = hr; + public Win32Exception(int code) { + this(code, W32Errors.HRESULT_FROM_WIN32(code)); } + /** - * New Win32 exception from an error code, usually obtained from GetLastError. - * @param code - * Error code. + * New Win32 exception from HRESULT. + * @param hr HRESULT */ - public Win32Exception(int code) { - this(W32Errors.HRESULT_FROM_WIN32(code)); + public Win32Exception(HRESULT hr) { + this(W32Errors.HRESULT_CODE(hr.intValue()), hr); + } + + protected Win32Exception(int code, HRESULT hr) { + this(code, hr, Kernel32Util.formatMessage(hr)); + } + + protected Win32Exception(int code, HRESULT hr, String msg) { + super(code, msg); + _hr = hr; } } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/WinBase.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/WinBase.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/WinBase.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/WinBase.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,36 +1,52 @@ /* 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * You can freely decide which license you want to apply to + * the project. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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 java.text.DateFormat; import java.util.Arrays; +import java.util.Calendar; import java.util.Date; import java.util.List; import com.sun.jna.Callback; +import com.sun.jna.Native; import com.sun.jna.Platform; import com.sun.jna.Pointer; import com.sun.jna.Structure; import com.sun.jna.Union; import com.sun.jna.platform.win32.WinNT.HANDLE; +import com.sun.jna.platform.win32.WinNT.LARGE_INTEGER; import com.sun.jna.ptr.ByteByReference; -import com.sun.jna.win32.StdCallLibrary; +import com.sun.jna.win32.StdCallLibrary.StdCallCallback; +import com.sun.jna.win32.W32APITypeMapper; /** * Ported from Winbase.h (kernel32.dll/kernel services). * Microsoft Windows SDK 6.0A. * @author dblock[at]dblock.org */ -public interface WinBase extends StdCallLibrary, WinDef, BaseTSD { +public interface WinBase extends WinDef, BaseTSD { /** Constant value representing an invalid HANDLE. */ HANDLE INVALID_HANDLE_VALUE = @@ -41,29 +57,29 @@ int WAIT_OBJECT_0 = ((NTStatus.STATUS_WAIT_0 ) + 0 ); int WAIT_ABANDONED = ((NTStatus.STATUS_ABANDONED_WAIT_0 ) + 0 ); int WAIT_ABANDONED_0 = ((NTStatus.STATUS_ABANDONED_WAIT_0 ) + 0 ); - + /** * Maximum computer name length. * The value is 15 on Mac, 31 on everything else. */ int MAX_COMPUTERNAME_LENGTH = Platform.isMac() ? 15 : 31; - + /** - * This logon type is intended for users who will be interactively using the computer, such - * as a user being logged on by a terminal server, remote shell, or similar process. This - * logon type has the additional expense of caching logon information for disconnected operations; - * therefore, it is inappropriate for some client/server applications, such as a mail server. + * This logon type is intended for users who will be interactively using the computer, such + * as a user being logged on by a terminal server, remote shell, or similar process. This + * logon type has the additional expense of caching logon information for disconnected operations; + * therefore, it is inappropriate for some client/server applications, such as a mail server. */ int LOGON32_LOGON_INTERACTIVE = 2; /** - * This logon type is intended for high performance servers to authenticate plaintext passwords. + * This logon type is intended for high performance servers to authenticate plaintext passwords. * The LogonUser function does not cache credentials for this logon type. */ int LOGON32_LOGON_NETWORK = 3; /** - * This logon type is intended for batch servers, where processes may be executing on behalf - * of a user without their direct intervention. This type is also for higher performance servers - * that process many plaintext authentication attempts at a time, such as mail or Web servers. + * This logon type is intended for batch servers, where processes may be executing on behalf + * of a user without their direct intervention. This type is also for higher performance servers + * that process many plaintext authentication attempts at a time, such as mail or Web servers. * The LogonUser function does not cache credentials for this logon type. */ int LOGON32_LOGON_BATCH = 4; @@ -72,32 +88,32 @@ */ int LOGON32_LOGON_SERVICE = 5; /** - * This logon type is for GINA DLLs that log on users who will be interactively using the computer. + * This logon type is for GINA DLLs that log on users who will be interactively using the computer. * This logon type can generate a unique audit record that shows when the workstation was unlocked. */ int LOGON32_LOGON_UNLOCK = 7; /** - * This logon type preserves the name and password in the authentication package, which allows the - * server to make connections to other network servers while impersonating the client. A server can - * accept plaintext credentials from a client, call LogonUser, verify that the user can access the + * This logon type preserves the name and password in the authentication package, which allows the + * server to make connections to other network servers while impersonating the client. A server can + * accept plaintext credentials from a client, call LogonUser, verify that the user can access the * system across the network, and still communicate with other servers. */ int LOGON32_LOGON_NETWORK_CLEARTEXT = 8; /** - * This logon type allows the caller to clone its current token and specify new credentials for - * outbound connections. The new logon session has the same local identifier but uses different - * credentials for other network connections. This logon type is supported only by the + * This logon type allows the caller to clone its current token and specify new credentials for + * outbound connections. The new logon session has the same local identifier but uses different + * credentials for other network connections. This logon type is supported only by the * LOGON32_PROVIDER_WINNT50 logon provider. */ int LOGON32_LOGON_NEW_CREDENTIALS = 9; /** - * Use the standard logon provider for the system. The default security provider is negotiate, - * unless you pass NULL for the domain name and the user name is not in UPN format. In this case, - * the default provider is NTLM. + * Use the standard logon provider for the system. The default security provider is negotiate, + * unless you pass NULL for the domain name and the user name is not in UPN format. In this case, + * the default provider is NTLM. */ int LOGON32_PROVIDER_DEFAULT = 0; - + /** * Use the Windows NT 3.5 logon provider. */ @@ -109,14 +125,14 @@ /** * Use the negotiate logon provider. */ - int LOGON32_PROVIDER_WINNT50 = 3; - + int LOGON32_PROVIDER_WINNT50 = 3; + /** * If this flag is set, a child process created with the bInheritHandles parameter of * CreateProcess set to TRUE will inherit the object handle. */ int HANDLE_FLAG_INHERIT = 1; - + /** * If this flag is set, calling the {@link Kernel32#CloseHandle} function will not * close the object handle. @@ -133,7 +149,7 @@ int STARTF_FORCEONFEEDBACK = 0x040; int STARTF_FORCEOFFFEEDBACK = 0x080; int STARTF_USESTDHANDLES = 0x100; - + // Process Creation flags int DEBUG_PROCESS = 0x00000001; int DEBUG_ONLY_THIS_PROCESS = 0x00000002; @@ -164,37 +180,51 @@ int FILE_USER_DISALLOWED = 7; int FILE_READ_ONLY = 8; int FILE_DIR_DISALOWED = 9; - + /* Open encrypted files raw flags */ int CREATE_FOR_IMPORT = 1; int CREATE_FOR_DIR = 2; int OVERWRITE_HIDDEN = 4; - + /* Invalid return values */ int INVALID_FILE_SIZE = 0xFFFFFFFF; int INVALID_SET_FILE_POINTER = 0xFFFFFFFF; int INVALID_FILE_ATTRIBUTES = 0xFFFFFFFF; - + /** * Return code for a process still active. */ int STILL_ACTIVE = WinNT.STATUS_PENDING; + // Codes for FILE_INFO_BY_HANDLE_CLASS taken from Winbase.h + int FileBasicInfo = 0; + int FileStandardInfo = 1; + int FileNameInfo = 2; + int FileRenameInfo = 3; + int FileDispositionInfo = 4; + int FileAllocationInfo = 5; + int FileEndOfFileInfo = 6; + int FileStreamInfo = 7; + int FileCompressionInfo = 8; + int FileAttributeTagInfo = 9; + int FileIdBothDirectoryInfo = 10; // 0xA + int FileIdBothDirectoryRestartInfo = 11; // 0xB + int FileIoPriorityHintInfo = 12; // 0xC + int FileRemoteProtocolInfo = 13; // 0xD + int FileFullDirectoryInfo = 14; // 0xE + int FileFullDirectoryRestartInfo = 15; // 0xF + int FileStorageInfo = 16; // 0x10 + int FileAlignmentInfo = 17; // 0x11 + int FileIdInfo = 18; // 0x12 + int FileIdExtdDirectoryInfo = 19; // 0x13 + int FileIdExtdDirectoryRestartInfo = 20; // 0x14 + /** - * The FILETIME structure is a 64-bit value representing the number of - * 100-nanosecond intervals since January 1, 1601 (UTC). - * Conversion code in this class Copyright 2002-2004 Apache Software Foundation. - * @author Rainer Klute (klute@rainer-klute.de) for the Apache Software Foundation (org.apache.poi.hpsf) + * Contains the basic information for a file. Used for file handles. */ - public static class FILETIME extends Structure { - public int dwLowDateTime; - public int dwHighDateTime; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "dwLowDateTime", "dwHighDateTime" }); - } + public static class FILE_BASIC_INFO extends Structure { - public static class ByReference extends FILETIME implements Structure.ByReference { + public static class ByReference extends FILE_BASIC_INFO implements Structure.ByReference { public ByReference() { } @@ -203,1504 +233,2340 @@ } } - public FILETIME(Date date) { - long rawValue = dateToFileTime(date); - dwHighDateTime = (int)(rawValue >> 32 & 0xffffffffL); - dwLowDateTime = (int)(rawValue & 0xffffffffL); - } - - public FILETIME() { - } + /** + * The time the file was created in FILETIME format, which is a 64-bit value + * representing the number of 100-nanosecond intervals since January 1, 1601 (UTC). + */ + public LARGE_INTEGER CreationTime; - public FILETIME(Pointer memory) { - super(memory); - read(); - } + /** + * The time the file was last accessed in FILETIME format. + */ + public LARGE_INTEGER LastAccessTime; /** - *

    The difference between the Windows epoch (1601-01-01 - * 00:00:00) and the Unix epoch (1970-01-01 00:00:00) in - * milliseconds: 11644473600000L. (Use your favorite spreadsheet - * program to verify the correctness of this value. By the way, - * did you notice that you can tell from the epochs which - * operating system is the modern one? :-))

    + * The time the file was last written to in FILETIME format. */ - private static final long EPOCH_DIFF = 11644473600000L; - + public LARGE_INTEGER LastWriteTime; + /** - *

    Converts a Windows FILETIME into a {@link Date}. The Windows - * FILETIME structure holds a date and time associated with a - * file. The structure identifies a 64-bit integer specifying the - * number of 100-nanosecond intervals which have passed since - * January 1, 1601. This 64-bit value is split into the two double - * words stored in the structure.

    - * - * @param high The higher double word of the FILETIME structure. - * @param low The lower double word of the FILETIME structure. - * @return The Windows FILETIME as a {@link Date}. + * The time the file was changed in FILETIME format. */ - public static Date filetimeToDate(final int high, final int low) { - final long filetime = (long) high << 32 | low & 0xffffffffL; - final long ms_since_16010101 = filetime / (1000 * 10); - final long ms_since_19700101 = ms_since_16010101 - EPOCH_DIFF; - return new Date(ms_since_19700101); - } - + public LARGE_INTEGER ChangeTime; + /** - *

    Converts a {@link Date} into a filetime.

    - * - * @param date The date to be converted - * @return The filetime - * - * @see #filetimeToDate + * The file attributes. For a list of attributes, see File Attribute Constants. + * If this is set to 0 in a FILE_BASIC_INFO structure passed to SetFileInformationByHandle + * then none of the attributes are changed. */ - public static long dateToFileTime(final Date date) { - final long ms_since_19700101 = date.getTime(); - final long ms_since_16010101 = ms_since_19700101 + EPOCH_DIFF; - return ms_since_16010101 * 1000 * 10; - } - - public Date toDate() { - return filetimeToDate(dwHighDateTime, dwLowDateTime); - } - - public long toLong() { - return toDate().getTime(); + public int FileAttributes; + + public static int sizeOf() + { + return Native.getNativeSize(FILE_BASIC_INFO.class, null); } - - public String toString() { - return super.toString() + ": " + toDate().toString(); //$NON-NLS-1$ + + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "CreationTime", "LastAccessTime", "LastWriteTime", "ChangeTime", "FileAttributes" }); } - } - - /* Local Memory Flags */ - int LMEM_FIXED = 0x0000; - int LMEM_MOVEABLE = 0x0002; - int LMEM_NOCOMPACT = 0x0010; - int LMEM_NODISCARD = 0x0020; - int LMEM_ZEROINIT = 0x0040; - int LMEM_MODIFY = 0x0080; - int LMEM_DISCARDABLE = 0x0F00; - int LMEM_VALID_FLAGS = 0x0F72; - int LMEM_INVALID_HANDLE = 0x8000; - int LHND = (LMEM_MOVEABLE | LMEM_ZEROINIT); - int LPTR = (LMEM_FIXED | LMEM_ZEROINIT); + public FILE_BASIC_INFO() { + super(); + } - /* Flags returned by LocalFlags (in addition to LMEM_DISCARDABLE) */ - int LMEM_DISCARDED = 0x4000; - int LMEM_LOCKCOUNT = 0x00FF; - - /** - * Specifies a date and time, using individual members for the month, - * day, year, weekday, hour, minute, second, and millisecond. The time - * is either in coordinated universal time (UTC) or local time, depending - * on the function that is being called. - * http://msdn.microsoft.com/en-us/library/ms724950(VS.85).aspx - */ - public static class SYSTEMTIME extends Structure { - // The year. The valid values for this member are 1601 through 30827. - public short wYear; - // The month. The valid values for this member are 1 through 12. - public short wMonth; - // The day of the week. The valid values for this member are 0 through 6. - public short wDayOfWeek; - // The day of the month. The valid values for this member are 1 through 31. - public short wDay; - // The hour. The valid values for this member are 0 through 23. - public short wHour; - // The minute. The valid values for this member are 0 through 59. - public short wMinute; - // The second. The valid values for this member are 0 through 59. - public short wSecond; - // The millisecond. The valid values for this member are 0 through 999. - public short wMilliseconds; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "wYear", "wMonth", "wDayOfWeek", "wDay", "wHour", "wMinute", "wSecond", "wMilliseconds" }); + public FILE_BASIC_INFO(Pointer memory) { + super(memory); + read(); + // This is admittedly odd, but the read() doesn't properly initialize the LARGE_INTEGERs via contructors, so do so here. + this.CreationTime = new LARGE_INTEGER(this.CreationTime.getValue()); + this.LastAccessTime = new LARGE_INTEGER(this.LastAccessTime.getValue()); + this.LastWriteTime = new LARGE_INTEGER(this.LastWriteTime.getValue()); + this.ChangeTime = new LARGE_INTEGER(this.ChangeTime.getValue()); + } + + public FILE_BASIC_INFO(FILETIME CreationTime, + FILETIME LastAccessTime, + FILETIME LastWriteTime, + FILETIME ChangeTime, + int FileAttributes) { + this.CreationTime = new LARGE_INTEGER(CreationTime.toTime()); + this.LastAccessTime = new LARGE_INTEGER(LastAccessTime.toTime()); + this.LastWriteTime = new LARGE_INTEGER(LastWriteTime.toTime()); + this.ChangeTime = new LARGE_INTEGER(ChangeTime.toTime()); + this.FileAttributes = FileAttributes; + write(); + } + + public FILE_BASIC_INFO(LARGE_INTEGER CreationTime, + LARGE_INTEGER LastAccessTime, + LARGE_INTEGER LastWriteTime, + LARGE_INTEGER ChangeTime, + int FileAttributes) { + this.CreationTime = CreationTime; + this.LastAccessTime = LastAccessTime; + this.LastWriteTime = LastWriteTime; + this.ChangeTime = ChangeTime; + this.FileAttributes = FileAttributes; + write(); } } - - /** - * Specifies settings for a time zone. - * http://msdn.microsoft.com/en-us/library/windows/desktop/ms725481(v=vs.85).aspx - */ - public static class TIME_ZONE_INFORMATION extends Structure { - public LONG Bias; - public String StandardName; - public SYSTEMTIME StandardDate; - public LONG StandardBias; - public String DaylightName; - public SYSTEMTIME DaylightDate; - public LONG DaylightBias; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "Bias", "StandardName", "StandardDate", "StandardBias", "DaylightName", "DaylightDate", "DaylightBias" }); - } - } - - /** - * The lpBuffer parameter is a pointer to a PVOID pointer, and that the nSize - * parameter specifies the minimum number of TCHARs to allocate for an output - * message buffer. The function allocates a buffer large enough to hold the - * formatted message, and places a pointer to the allocated buffer at the address - * specified by lpBuffer. The caller should use the LocalFree function to free - * the buffer when it is no longer needed. - */ - int FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100; - /** - * Insert sequences in the message definition are to be ignored and passed through - * to the output buffer unchanged. This flag is useful for fetching a message for - * later formatting. If this flag is set, the Arguments parameter is ignored. - */ - int FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200; - /** - * The lpSource parameter is a pointer to a null-terminated message definition. - * The message definition may contain insert sequences, just as the message text - * in a message table resource may. Cannot be used with FORMAT_MESSAGE_FROM_HMODULE - * or FORMAT_MESSAGE_FROM_SYSTEM. - */ - int FORMAT_MESSAGE_FROM_STRING = 0x00000400; - /** - * The lpSource parameter is a module handle containing the message-table - * resource(s) to search. If this lpSource handle is NULL, the current process's - * application image file will be searched. Cannot be used with - * FORMAT_MESSAGE_FROM_STRING. - */ - int FORMAT_MESSAGE_FROM_HMODULE = 0x00000800; - /** - * The function should search the system message-table resource(s) for the - * requested message. If this flag is specified with FORMAT_MESSAGE_FROM_HMODULE, - * the function searches the system message table if the message is not found in - * the module specified by lpSource. Cannot be used with FORMAT_MESSAGE_FROM_STRING. - * If this flag is specified, an application can pass the result of the - * GetLastError function to retrieve the message text for a system-defined error. - */ - int FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000; - /** - * The Arguments parameter is not a va_list structure, but is a pointer to an array - * of values that represent the arguments. This flag cannot be used with 64-bit - * argument values. If you are using 64-bit values, you must use the va_list - * structure. - */ - int FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x00002000; /** - * The drive type cannot be determined. - */ - int DRIVE_UNKNOWN = 0; - /** - * The root path is invalid, for example, no volume is mounted at the path. - */ - int DRIVE_NO_ROOT_DIR = 1; - /** - * The drive is a type that has removable media, for example, a floppy drive - * or removable hard disk. - */ - int DRIVE_REMOVABLE = 2; - /** - * The drive is a type that cannot be removed, for example, a fixed hard drive. - */ - int DRIVE_FIXED = 3; - /** - * The drive is a remote (network) drive. - */ - int DRIVE_REMOTE = 4; - /** - * The drive is a CD-ROM drive. - */ - int DRIVE_CDROM = 5; - /** - * The drive is a RAM disk. - */ - int DRIVE_RAMDISK = 6; - - /** - * The OVERLAPPED structure contains information used in - * asynchronous (or overlapped) input and output (I/O). + * Receives extended information for the file. Used for file handles. Use only when calling GetFileInformationByHandleEx. */ - public static class OVERLAPPED extends Structure { - public ULONG_PTR Internal; - public ULONG_PTR InternalHigh; - public int Offset; - public int OffsetHigh; - public HANDLE hEvent; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "Internal", "InternalHigh", "Offset", "OffsetHigh", "hEvent" }); - } - } - - int INFINITE = 0xFFFFFFFF; + public static class FILE_STANDARD_INFO extends Structure { - /** - * Contains information about the current computer system. This includes the architecture and - * type of the processor, the number of processors in the system, the page size, and other such - * information. - */ - public static class SYSTEM_INFO extends Structure { - - /** Unnamed inner structure. */ - public static class PI extends Structure { - - public static class ByReference extends PI implements Structure.ByReference { - + public static class ByReference extends FILE_STANDARD_INFO implements Structure.ByReference { + public ByReference() { } - /** - * System's processor architecture. - * This value can be one of the following values: - * - * PROCESSOR_ARCHITECTURE_UNKNOWN - * PROCESSOR_ARCHITECTURE_INTEL - * PROCESSOR_ARCHITECTURE_IA64 - * PROCESSOR_ARCHITECTURE_AMD64 - */ - public WORD wProcessorArchitecture; - /** - * Reserved for future use. - */ - public WORD wReserved; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "wProcessorArchitecture", "wReserved" }); - } - } - - /** Unnamed inner union. */ - public static class UNION extends Union { - - public static class ByReference extends UNION implements Structure.ByReference { - + public ByReference(Pointer memory) { + super(memory); } - - /** - * An obsolete member that is retained for compatibility with Windows NT 3.5 and earlier. - * New applications should use the wProcessorArchitecture branch of the union. - * Windows Me/98/95: The system always sets this member to zero, the value defined - * for PROCESSOR_ARCHITECTURE_INTEL. - */ - public DWORD dwOemID; - /** - * Processor architecture (unnamed struct). - */ - public PI pi; } - + /** - * Processor architecture (unnamed union). + * The amount of space that is allocated for the file. */ - public UNION processorArchitecture; + public LARGE_INTEGER AllocationSize; + /** - * Page size and the granularity of page protection and commitment. + * The end of the file. */ - public DWORD dwPageSize; + public LARGE_INTEGER EndOfFile; + /** - * Pointer to the lowest memory address accessible to applications and dynamic-link libraries (DLLs). + * The number of links to the file. */ - public Pointer lpMinimumApplicationAddress; + public int NumberOfLinks; + /** - * Pointer to the highest memory address accessible to applications and DLLs. + * TRUE if the file in the delete queue; otherwise, false. */ - public Pointer lpMaximumApplicationAddress; - /** - * Mask representing the set of processors configured into the system. Bit 0 is processor 0; bit 31 is processor 31. - */ - public DWORD_PTR dwActiveProcessorMask; - /** - * Number of processors in the system. - */ - public DWORD dwNumberOfProcessors; - /** - * An obsolete member that is retained for compatibility with Windows NT 3.5 and Windows Me/98/95. - * Use the wProcessorArchitecture, wProcessorLevel, and wProcessorRevision members to determine - * the type of processor. - * PROCESSOR_INTEL_386 - * PROCESSOR_INTEL_486 - * PROCESSOR_INTEL_PENTIUM - */ - public DWORD dwProcessorType; - /** - * Granularity for the starting address at which virtual memory can be allocated. - */ - public DWORD dwAllocationGranularity; + public boolean DeletePending; + /** - * System's architecture-dependent processor level. It should be used only for display purposes. - * To determine the feature set of a processor, use the IsProcessorFeaturePresent function. - * If wProcessorArchitecture is PROCESSOR_ARCHITECTURE_INTEL, wProcessorLevel is defined by the CPU vendor. - * If wProcessorArchitecture is PROCESSOR_ARCHITECTURE_IA64, wProcessorLevel is set to 1. + * TRUE if the file is a directory; otherwise, false. */ - public WORD wProcessorLevel; + public boolean Directory; + + public static int sizeOf() + { + return Native.getNativeSize(FILE_STANDARD_INFO.class, null); + } + + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "AllocationSize", "EndOfFile", "NumberOfLinks", "DeletePending", "Directory" }); + } + + public FILE_STANDARD_INFO() { + super(); + } + + public FILE_STANDARD_INFO(Pointer memory) { + super(memory); + read(); + } + + public FILE_STANDARD_INFO(LARGE_INTEGER AllocationSize, + LARGE_INTEGER EndOfFile, + int NumberOfLinks, + boolean DeletePending, + boolean Directory) { + this.AllocationSize = AllocationSize; + this.EndOfFile = EndOfFile; + this.NumberOfLinks = NumberOfLinks; + this.DeletePending = DeletePending; + this.Directory = Directory; + write(); + } + } + + /** + * Indicates whether a file should be deleted. Used for any handles. Use only when calling SetFileInformationByHandle. + */ + public static class FILE_DISPOSITION_INFO extends Structure { + + public static class ByReference extends FILE_DISPOSITION_INFO implements Structure.ByReference { + public ByReference() { + } + + public ByReference(Pointer memory) { + super(memory); + } + } + /** - * Architecture-dependent processor revision. + * Indicates whether the file should be deleted. Set to TRUE to delete the file. This member + * has no effect if the handle was opened with FILE_FLAG_DELETE_ON_CLOSE. */ - public WORD wProcessorRevision; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "processorArchitecture", "dwPageSize", "lpMinimumApplicationAddress", "lpMaximumApplicationAddress", "dwActiveProcessorMask", "dwNumberOfProcessors", "dwProcessorType", "dwAllocationGranularity", "wProcessorLevel", "wProcessorRevision"}); + public boolean DeleteFile; + + public static int sizeOf() + { + return Native.getNativeSize(FILE_DISPOSITION_INFO.class, null); + } + + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "DeleteFile" }); + } + + public FILE_DISPOSITION_INFO () { + super(); + } + + public FILE_DISPOSITION_INFO (Pointer memory) { + super(memory); + read(); + } + + public FILE_DISPOSITION_INFO (boolean DeleteFile) { + this.DeleteFile = DeleteFile; + write(); } } - + /** - * Contains information about the current state of both physical and virtual memory, including - * extended memory. The GlobalMemoryStatusEx function stores information in this structure. + * Receives extended information for the file. Used for file handles. Use only when calling GetFileInformationByHandleEx. */ - public static class MEMORYSTATUSEX extends Structure { - /** - * The size of the structure, in bytes. - */ - public DWORD dwLength; + public static class FILE_COMPRESSION_INFO extends Structure { + + public static class ByReference extends FILE_COMPRESSION_INFO implements Structure.ByReference { + public ByReference() { + } + + public ByReference(Pointer memory) { + super(memory); + } + } + /** - * A number between 0 and 100 that specifies the approximate percentage of physical memory - * that is in use (0 indicates no memory use and 100 indicates full memory use). + * The file size of the compressed file. */ - public DWORD dwMemoryLoad; + public LARGE_INTEGER CompressedFileSize; + /** - * The amount of actual physical memory, in bytes. + * The compression format that is used to compress the file. */ - public DWORDLONG ullTotalPhys; + public short CompressionFormat; + /** - * The amount of physical memory currently available, in bytes. This is the amount of physical - * memory that can be immediately reused without having to write its contents to disk first. - * It is the sum of the size of the standby, free, and zero lists. + * The factor that the compression uses. */ - public DWORDLONG ullAvailPhys; + public byte CompressionUnitShift; + /** - * The current committed memory limit for the system or the current process, whichever is smaller, in bytes. + * The number of chunks that are shifted by compression. */ - public DWORDLONG ullTotalPageFile; + public byte ChunkShift; + /** - * The maximum amount of memory the current process can commit, in bytes. This value is equal to or smaller - * than the system-wide available commit value. + * The number of clusters that are shifted by compression. */ - public DWORDLONG ullAvailPageFile; + public byte ClusterShift; + /** - * The size of the user-mode portion of the virtual address space of the calling process, in bytes. + * Reserved */ - public DWORDLONG ullTotalVirtual; + public byte[] Reserved = new byte[3]; + + public static int sizeOf() + { + return Native.getNativeSize(FILE_COMPRESSION_INFO.class, null); + } + + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "CompressedFileSize", "CompressionFormat", "CompressionUnitShift", "ChunkShift", "ClusterShift", "Reserved" }); + } + + public FILE_COMPRESSION_INFO() { + super(W32APITypeMapper.DEFAULT); + } + + public FILE_COMPRESSION_INFO(Pointer memory) { + super(memory, Structure.ALIGN_DEFAULT, W32APITypeMapper.DEFAULT); + read(); + } + + public FILE_COMPRESSION_INFO(LARGE_INTEGER CompressedFileSize, + short CompressionFormat, + byte CompressionUnitShift, + byte ChunkShift, + byte ClusterShift) { + this.CompressedFileSize = CompressedFileSize; + this.CompressionFormat = CompressionFormat; + this.CompressionUnitShift = CompressionUnitShift; + this.ChunkShift = ChunkShift; + this.ClusterShift = ClusterShift; + this.Reserved = new byte[3]; + write(); + } + } + + /** + * Receives the requested file attribute information. Used for any handles. Use only when calling GetFileInformationByHandleEx. + */ + public static class FILE_ATTRIBUTE_TAG_INFO extends Structure { + + public static class ByReference extends FILE_ATTRIBUTE_TAG_INFO implements Structure.ByReference { + public ByReference() { + } + + public ByReference(Pointer memory) { + super(memory); + } + } + /** - * The amount of unreserved and uncommitted memory currently in the user-mode portion of the - * virtual address space of the calling process, in bytes. + * The file attribute information. */ - public DWORDLONG ullAvailVirtual; + public int FileAttributes; + /** - * Reserved. This value is always 0. + * The reparse tag. */ - public DWORDLONG ullAvailExtendedVirtual; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "dwLength", "dwMemoryLoad", "ullTotalPhys", "ullAvailPhys", "ullTotalPageFile", "ullAvailPageFile", "ullTotalVirtual", "ullAvailVirtual", "ullAvailExtendedVirtual" }); + public int ReparseTag; + + public static int sizeOf() + { + return Native.getNativeSize(FILE_ATTRIBUTE_TAG_INFO.class, null); } - - public MEMORYSTATUSEX() { - dwLength = new DWORD(size()); + + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "FileAttributes", "ReparseTag" }); } - }; - + + public FILE_ATTRIBUTE_TAG_INFO() { + super(); + } + + public FILE_ATTRIBUTE_TAG_INFO(Pointer memory) { + super(memory); + read(); + } + + public FILE_ATTRIBUTE_TAG_INFO(int FileAttributes, + int ReparseTag) { + this.FileAttributes = FileAttributes; + this.ReparseTag = ReparseTag; + write(); + } + } + /** - * The SECURITY_ATTRIBUTES structure contains the security descriptor for an - * object and specifies whether the handle retrieved by specifying this - * structure is inheritable. This structure provides security settings for - * objects created by various functions, such as {@link Kernel32#CreateFile}, - * {@link Kernel32#CreatePipe}, or {@link Advapi32#RegCreateKeyEx}. + * Contains identification information for a file. This structure is returned from the + * GetFileInformationByHandleEx function when FileIdInfo is passed in the + * FileInformationClass parameter. */ - public static class SECURITY_ATTRIBUTES extends Structure { - /** - * The size of the structure, in bytes. - */ - public DWORD dwLength; - + public static class FILE_ID_INFO extends Structure { + + public static class ByReference extends FILE_ID_INFO implements Structure.ByReference { + public ByReference() { + } + + public ByReference(Pointer memory) { + super(memory); + } + } + + public static class FILE_ID_128 extends Structure { + public BYTE[] Identifier = new BYTE[16]; + + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "Identifier" }); + } + + public FILE_ID_128() { + super(); + } + + public FILE_ID_128(Pointer memory) { + super(memory); + read(); + } + + public FILE_ID_128(BYTE[] Identifier) { + this.Identifier = Identifier; + write(); + } + } + /** - * A pointer to a SECURITY_DESCRIPTOR structure that controls access to the object. + * The serial number of the volume that contains a file. */ - public Pointer lpSecurityDescriptor; - + public long VolumeSerialNumber; + /** - * A Boolean value that specifies whether the returned handle is inherited when - * a new process is created + * The end of the file. */ - public boolean bInheritHandle; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "dwLength", "lpSecurityDescriptor", "bInheritHandle" }); + public FILE_ID_128 FileId; + + public static int sizeOf() + { + return Native.getNativeSize(FILE_ID_INFO.class, null); } - - public SECURITY_ATTRIBUTES() { - dwLength = new DWORD(size()); + + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "VolumeSerialNumber", "FileId" }); + } + + public FILE_ID_INFO() { + super(); + } + + public FILE_ID_INFO(Pointer memory) { + super(memory); + read(); + } + + public FILE_ID_INFO(long VolumeSerialNumber, + FILE_ID_128 FileId) { + this.VolumeSerialNumber = VolumeSerialNumber; + this.FileId = FileId; + write(); } } - + + // FINDEX_INFO_LEVELS values defines values that are used with the FindFirstFileEx function to specify the information level of the returned data. + /** - * Specifies the window station, desktop, standard handles, and appearance of the main - * window for a process at creation time. + * The FindFirstFileEx function retrieves a standard set of attribute information. The data is returned + * in a WIN32_FIND_DATA structure. */ - public static class STARTUPINFO extends Structure { + int FindExInfoStandard = 0; + + /** + * The FindFirstFileEx function does not query the short file name, improving overall enumeration speed. The data is + * returned in a WIN32_FIND_DATA structure, and the cAlternateFileName member is always a NULL string. + */ + int FindExInfoBasic = 1; + /** + * This value is used for validation. Supported values are less than this value. + */ + int FindExInfoMaxInfoLevel = 2; + + // FINDEX_SEARCH_OPS values defines values that are used with the FindFirstFileEx function to specify the type of filtering to perform. + /** + * The search for a file that matches a specified file name. The lpSearchFilter parameter of FindFirstFileEx + * must be NULL when this search operation is used. + */ + int FindExSearchNameMatch = 0; + + /** + * This is an advisory flag. If the file system supports directory filtering, the function searches for a file that + * matches the specified name and is also a directory. If the file system does not support directory filtering, + * this flag is silently ignored. + * The lpSearchFilter parameter of the FindFirstFileEx function must be NULL when this search value is used. + * If directory filtering is desired, this flag can be used on all file systems, but because it is an advisory + * flag and only affects file systems that support it, the application must examine the file attribute data stored + * in the lpFindFileData parameter of the FindFirstFileEx function to determine whether the function has returned + * a handle to a directory. + */ + int FindExSearchLimitToDirectories = 1; + + /** + * This filtering type is not available. For more information, see Device Interface Classes. + */ + int FindExSearchLimitToDevices = 2; + + /** + * Contains information about the file that is found by the FindFirstFile, FindFirstFileEx, or FindNextFile function. + */ + public static class WIN32_FIND_DATA extends Structure { + + public static class ByReference extends WIN32_FIND_DATA implements Structure.ByReference { + public ByReference() { + } + + public ByReference(Pointer memory) { + super(memory); + } + } + /** - * The size of the structure, in bytes. + * The file attributes of a file. For possible values and their descriptions, + * see File Attribute Constants. The FILE_ATTRIBUTE_SPARSE_FILE attribute on + * the file is set if any of the streams of the file have ever been sparse. */ - public DWORD cb; - - /** - * Reserved; must be NULL. - */ - public String lpReserved; - + public int dwFileAttributes; + /** - * The name of the desktop, or the name of both the desktop and window station for this process. - * A backslash in the string indicates that the string includes both the desktop and window - * station names. For more information, see Thread Connection to a Desktop. + * A FILETIME structure that specifies when a file or directory was created. If + * the underlying file system does not support creation time, this member is zero. */ - public String lpDesktop; - + public FILETIME ftCreationTime; + /** - * For console processes, this is the title displayed in the title bar - * if a new console window is created. If NULL, the name of the - * executable file is used as the window title instead. This parameter - * must be NULL for GUI or console processes that do not create a new - * console window. + * A FILETIME structure. For a file, the structure specifies when the file was last + * read from, written to, or for executable files, run. For a directory, the structure + * specifies when the directory is created. If the underlying file system does not + * support last access time, this member is zero. On the FAT file system, the + * specified date for both files and directories is correct, but the time of day is + * always set to midnight. */ - public String lpTitle; - + public FILETIME ftLastAccessTime; + /** - * If dwFlags specifies STARTF_USEPOSITION, this member is the x offset - * of the upper left corner of a window if a new window is created, in - * pixels. Otherwise, this member is ignored. - * - * The offset is from the upper left corner of the screen. For GUI - * processes, the specified position is used the first time the new - * process calls CreateWindow to create an overlapped window if the x - * parameter of CreateWindow is CW_USEDEFAULT. + * A FILETIME structure. For a file, the structure specifies when the file was last + * written to, truncated, or overwritten, for example, when WriteFile or SetEndOfFile + * are used. The date and time are not updated when file attributes or security descriptors + * are changed. For a directory, the structure specifies when the directory is created. + * If the underlying file system does not support last write time, this member is zero. */ - public DWORD dwX; + public FILETIME ftLastWriteTime; /** - * If dwFlags specifies STARTF_USEPOSITION, this member is the y offset - * of the upper left corner of a window if a new window is created, in - * pixels. Otherwise, this member is ignored. - * - * The offset is from the upper left corner of the screen. For GUI - * processes, the specified position is used the first time the new - * process calls CreateWindow to create an overlapped window if the y - * parameter of CreateWindow is CW_USEDEFAULT. + * The high-order DWORD value of the file size, in bytes. This value is zero unless the + * file size is greater than MAXDWORD. + * The size of the file is equal to (nFileSizeHigh * (MAXDWORD+1)) + nFileSizeLow. */ - public DWORD dwY; + public int nFileSizeHigh; /** - * If dwFlags specifies STARTF_USESIZE, this member is the width of the - * window if a new window is created, in pixels. Otherwise, this member - * is ignored. - * - * For GUI processes, this is used only the first time the new process - * calls CreateWindow to create an overlapped window if the nWidth - * parameter of CreateWindow is CW_USEDEFAULT. + * The low-order DWORD value of the file size, in bytes. */ - public DWORD dwXSize; - + public int nFileSizeLow; + /** - * If dwFlags specifies STARTF_USESIZE, this member is the height of the - * window if a new window is created, in pixels. Otherwise, this member - * is ignored. - * - * For GUI processes, this is used only the first time the new process - * calls CreateWindow to create an overlapped window if the nHeight - * parameter of CreateWindow is CW_USEDEFAULT. + * If the dwFileAttributes member includes the FILE_ATTRIBUTE_REPARSE_POINT attribute, this member + * specifies the reparse point tag. Otherwise, this value is undefined and should not be used. + * For more information see Reparse Point Tags. + * + * IO_REPARSE_TAG_CSV (0x80000009) + * IO_REPARSE_TAG_DEDUP (0x80000013) + * IO_REPARSE_TAG_DFS (0x8000000A) + * IO_REPARSE_TAG_DFSR (0x80000012) + * IO_REPARSE_TAG_HSM (0xC0000004) + * IO_REPARSE_TAG_HSM2 (0x80000006) + * IO_REPARSE_TAG_MOUNT_POINT (0xA0000003) + * IO_REPARSE_TAG_NFS (0x80000014) + * IO_REPARSE_TAG_SIS (0x80000007) + * IO_REPARSE_TAG_SYMLINK (0xA000000C) + * IO_REPARSE_TAG_WIM (0x80000008) */ - public DWORD dwYSize; + public int dwReserved0; /** - * If dwFlags specifies STARTF_USECOUNTCHARS, if a new console window is - * created in a console process, this member specifies the screen buffer - * width, in character columns. Otherwise, this member is ignored. + * Reserved for future use. */ - public DWORD dwXCountChars; + public int dwReserved1; /** - * If dwFlags specifies STARTF_USECOUNTCHARS, if a new console window is - * created in a console process, this member specifies the screen buffer - * height, in character rows. Otherwise, this member is ignored. + * The name of the file. NOTE: When written from Native memory, this will be a null terminated string. + * Any characters after the null terminator are random memory. Use function getFileName to + * get a String with the name. */ - public DWORD dwYCountChars; + public char[] cFileName = new char[MAX_PATH]; /** - * If dwFlags specifies STARTF_USEFILLATTRIBUTE, this member is the - * initial text and background colors if a new console window is created - * in a console application. Otherwise, this member is ignored. - * - * This value can be any combination of the following values: - * FOREGROUND_BLUE, FOREGROUND_GREEN, FOREGROUND_RED, - * FOREGROUND_INTENSITY, BACKGROUND_BLUE, BACKGROUND_GREEN, - * BACKGROUND_RED, and BACKGROUND_INTENSITY. For example, the following - * combination of values produces red text on a white background: - * - * FOREGROUND_RED| BACKGROUND_RED| BACKGROUND_GREEN| BACKGROUND_BLUE + * An alternative name for the file. This name is in the classic 8.3 file name format. + * NOTE: When written from Native memory, this will be a null terminated string. + * Any characters after the null terminator are random memory. Use function getAlternateFileName to + * get a String with the alternate name. */ - public DWORD dwFillAttribute; + public char[] cAlternateFileName = new char[14]; + + public static int sizeOf() { + return Native.getNativeSize(WIN32_FIND_DATA.class, null); + } + + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "dwFileAttributes", "ftCreationTime", "ftLastAccessTime", "ftLastWriteTime", "nFileSizeHigh", "nFileSizeLow", "dwReserved0", "dwReserved1", "cFileName", "cAlternateFileName" }); + } + + public WIN32_FIND_DATA() { + super(W32APITypeMapper.DEFAULT); + } + + public WIN32_FIND_DATA(Pointer memory) { + super(memory, Structure.ALIGN_DEFAULT, W32APITypeMapper.DEFAULT); + read(); + } + + public WIN32_FIND_DATA(int dwFileAttributes, + FILETIME ftCreationTime, + FILETIME ftLastAccessTime, + FILETIME ftLastWriteTime, + int nFileSizeHigh, + int nFileSizeLow, + int dwReserved0, + int dwReserved1, + char[] cFileName, + char[] cAlternateFileName) { + this.dwFileAttributes = dwFileAttributes; + this.ftCreationTime = ftCreationTime; + this.ftLastAccessTime = ftLastAccessTime; + this.ftLastWriteTime = ftLastWriteTime; + this.nFileSizeHigh = nFileSizeHigh; + this.nFileSizeLow = nFileSizeLow; + this.dwReserved0 = dwReserved0; + this.cFileName = cFileName; + this.cAlternateFileName = cAlternateFileName; + write(); + } /** - * A bit field that determines whether certain STARTUPINFO members are - * used when the process creates a window. + * @return String containing the file name + */ + public String getFileName() { + return Native.toString(cFileName); + } + + /** + * @return String containing the alternate file name */ - public int dwFlags; + public String getAlternateFileName() { + return Native.toString(cAlternateFileName); + } + } + + /** + * The FILETIME structure is a 64-bit value representing the number of + * 100-nanosecond intervals since January 1, 1601 (UTC). + * Conversion code in this class Copyright 2002-2004 Apache Software Foundation. + * @author Rainer Klute (klute@rainer-klute.de) for the Apache Software Foundation (org.apache.poi.hpsf) + */ + public static class FILETIME extends Structure { + public int dwLowDateTime; + public int dwHighDateTime; + + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "dwLowDateTime", "dwHighDateTime" }); + } + + public static class ByReference extends FILETIME implements Structure.ByReference { + public ByReference() { + } + + public ByReference(Pointer memory) { + super(memory); + } + } + + public FILETIME(Date date) { + long rawValue = dateToFileTime(date); + dwHighDateTime = (int)(rawValue >> 32 & 0xffffffffL); + dwLowDateTime = (int)(rawValue & 0xffffffffL); + } /** - * If dwFlags specifies STARTF_USESHOWWINDOW, this member can be any of - * the values that can be specified in the nCmdShow parameter for the - * ShowWindow function, except for SW_SHOWDEFAULT. Otherwise, this - * member is ignored. - * - * For GUI processes, the first time ShowWindow is called, its nCmdShow - * parameter is ignored wShowWindow specifies the default value. In - * subsequent calls to ShowWindow, the wShowWindow member is used if the - * nCmdShow parameter of ShowWindow is set to SW_SHOWDEFAULT. + * Construct FILETIME from LARGE_INTEGER + * @param ft */ - public WORD wShowWindow; + public FILETIME(LARGE_INTEGER ft) { + dwHighDateTime = ft.getHigh().intValue(); + dwLowDateTime = ft.getLow().intValue(); + } + + public FILETIME() { + } + + public FILETIME(Pointer memory) { + super(memory); + read(); + } /** - * Reserved for use by the C Run-time; must be zero. + *

    The difference between the Windows epoch (1601-01-01 + * 00:00:00) and the Unix epoch (1970-01-01 00:00:00) in + * milliseconds: 11644473600000L. (Use your favorite spreadsheet + * program to verify the correctness of this value. By the way, + * did you notice that you can tell from the epochs which + * operating system is the modern one? :-))

    */ - public WORD cbReserved2; + private static final long EPOCH_DIFF = 11644473600000L; /** - * Reserved for use by the C Run-time; must be NULL. + *

    Converts a Windows FILETIME into a {@link Date}. The Windows + * FILETIME structure holds a date and time associated with a + * file. The structure identifies a 64-bit integer specifying the + * number of 100-nanosecond intervals which have passed since + * January 1, 1601. This 64-bit value is split into the two double + * words stored in the structure.

    + * + * @param high The higher double word of the FILETIME structure. + * @param low The lower double word of the FILETIME structure. + * @return The Windows FILETIME as a {@link Date}. */ - public ByteByReference lpReserved2; + public static Date filetimeToDate(final int high, final int low) { + final long filetime = (long) high << 32 | low & 0xffffffffL; + final long ms_since_16010101 = filetime / (1000 * 10); + final long ms_since_19700101 = ms_since_16010101 - EPOCH_DIFF; + return new Date(ms_since_19700101); + } /** - * If dwFlags specifies STARTF_USESTDHANDLES, this member is the - * standard input handle for the process. If STARTF_USESTDHANDLES is not - * specified, the default for standard input is the keyboard buffer. - * - * If dwFlags specifies STARTF_USEHOTKEY, this member specifies a hotkey - * value that is sent as the wParam parameter of a WM_SETHOTKEY message - * to the first eligible top-level window created by the application - * that owns the process. If the window is created with the WS_POPUP - * window style, it is not eligible unless the WS_EX_APPWINDOW extended - * window style is also set. For more information, see CreateWindowEx. - * - * Otherwise, this member is ignored. + *

    Converts a {@link Date} into a filetime.

    + * + * @param date The date to be converted + * @return The filetime + * + * @see #filetimeToDate */ - public HANDLE hStdInput; + public static long dateToFileTime(final Date date) { + final long ms_since_19700101 = date.getTime(); + final long ms_since_16010101 = ms_since_19700101 + EPOCH_DIFF; + return ms_since_16010101 * 1000 * 10; + } /** - * If dwFlags specifies STARTF_USESTDHANDLES, this member is the - * standard output handle for the process. Otherwise, this member is - * ignored and the default for standard output is the console window's - * buffer. + *

    Converts this filetime into a {@link Date}

    + * @return The {@link Date} represented by this filetime. */ - public HANDLE hStdOutput; + public Date toDate() { + return filetimeToDate(dwHighDateTime, dwLowDateTime); + } /** - * If dwFlags specifies STARTF_USESTDHANDLES, this member is the - * standard error handle for the process. Otherwise, this member is - * ignored and the default for standard error is the console window's - * buffer. + *

    Converts this filetime into a number of milliseconds which have + * passed since January 1, 1970 (UTC).

    + * @return This filetime as a number of milliseconds which have passed + * since January 1, 1970 (UTC) */ - public HANDLE hStdError; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "cb", "lpReserved", "lpDesktop", "lpTitle", "dwX", "dwY", "dwXSize", "dwYSize", "dwXCountChars", "dwYCountChars", "dwFillAttribute", "dwFlags", "wShowWindow", "cbReserved2", "lpReserved2", "hStdInput", "hStdOutput", "hStdError" }); + public long toTime() { + return toDate().getTime(); + } + + /** + *

    Converts this filetime into a number of milliseconds which have + * passed since January 1, 1970 (UTC).

    + * @return This filetime as a number of milliseconds which have passed + * since January 1, 1970 (UTC) + * @deprecated Replaced by {@link #toTime()} + */ + @Deprecated + public long toLong() { + return toDate().getTime(); + } + + /** + *

    Converts the two 32-bit unsigned integer parts of this filetime + * into a 64-bit unsigned integer representing the number of + * 100-nanosecond intervals since January 1, 1601 (UTC).

    + * @return This filetime as a 64-bit unsigned integer number of + * 100-nanosecond intervals since January 1, 1601 (UTC). + */ + public DWORDLONG toDWordLong() { + return new DWORDLONG((long) dwHighDateTime << 32 | dwLowDateTime & 0xffffffffL); + } + + @Override + public String toString() { + return super.toString() + ": " + toDate().toString(); //$NON-NLS-1$ + } + } + + /* Local Memory Flags */ + int LMEM_FIXED = 0x0000; + int LMEM_MOVEABLE = 0x0002; + int LMEM_NOCOMPACT = 0x0010; + int LMEM_NODISCARD = 0x0020; + int LMEM_ZEROINIT = 0x0040; + int LMEM_MODIFY = 0x0080; + int LMEM_DISCARDABLE = 0x0F00; + int LMEM_VALID_FLAGS = 0x0F72; + int LMEM_INVALID_HANDLE = 0x8000; + + int LHND = (LMEM_MOVEABLE | LMEM_ZEROINIT); + int LPTR = (LMEM_FIXED | LMEM_ZEROINIT); + + /* Flags returned by LocalFlags (in addition to LMEM_DISCARDABLE) */ + int LMEM_DISCARDED = 0x4000; + int LMEM_LOCKCOUNT = 0x00FF; + + /** + * Specifies a date and time, using individual members for the month, + * day, year, weekday, hour, minute, second, and millisecond. The time + * is either in coordinated universal time (UTC) or local time, depending + * on the function that is being called. + * @see SYSTEMTIME structure + */ + public static class SYSTEMTIME extends Structure { + // The year. The valid values for this member are 1601 through 30827. + public short wYear; + // The month. The valid values for this member are 1 through 12. + public short wMonth; + // The day of the week. The valid values for this member are 0 through 6. + public short wDayOfWeek; + // The day of the month. The valid values for this member are 1 through 31. + public short wDay; + // The hour. The valid values for this member are 0 through 23. + public short wHour; + // The minute. The valid values for this member are 0 through 59. + public short wMinute; + // The second. The valid values for this member are 0 through 59. + public short wSecond; + // The millisecond. The valid values for this member are 0 through 999. + public short wMilliseconds; + + public SYSTEMTIME() { + super(); + } + + public SYSTEMTIME(Date date) { + this(date.getTime()); + } + + public SYSTEMTIME(long timestamp) { + Calendar cal = Calendar.getInstance(); + cal.setTimeInMillis(timestamp); + fromCalendar(cal); + } + + public SYSTEMTIME(Calendar cal) { + fromCalendar(cal); + } + + public void fromCalendar(Calendar cal) { + wYear = (short) cal.get(Calendar.YEAR); + wMonth = (short) (1 + cal.get(Calendar.MONTH) - Calendar.JANUARY); // 1 = January + wDay = (short) cal.get(Calendar.DAY_OF_MONTH); + wHour = (short) cal.get(Calendar.HOUR_OF_DAY); + wMinute = (short) cal.get(Calendar.MINUTE); + wSecond = (short) cal.get(Calendar.SECOND); + wMilliseconds = (short) cal.get(Calendar.MILLISECOND); + wDayOfWeek = (short) (cal.get(Calendar.DAY_OF_WEEK) - Calendar.SUNDAY); // 0 = Sunday + } + + public Calendar toCalendar() { + Calendar cal = Calendar.getInstance(); + cal.set(Calendar.YEAR, wYear); + cal.set(Calendar.MONTH, Calendar.JANUARY + (wMonth - 1)); + cal.set(Calendar.DAY_OF_MONTH, wDay); + cal.set(Calendar.HOUR_OF_DAY, wHour); + cal.set(Calendar.MINUTE, wMinute); + cal.set(Calendar.SECOND, wSecond); + cal.set(Calendar.MILLISECOND, wMilliseconds); + return cal; + } + + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "wYear", "wMonth", "wDayOfWeek", "wDay", "wHour", "wMinute", "wSecond", "wMilliseconds" }); + } + + @Override + public String toString() { + // if not initialized, return the default representation + if ((wYear == 0) && (wMonth == 0) && (wDay == 0) + && (wHour == 0) && (wMinute == 0) && (wSecond == 0) + && (wMilliseconds == 0)) { + return super.toString(); + } + + DateFormat dtf = DateFormat.getDateTimeInstance(); + Calendar cal = toCalendar(); + return dtf.format(cal.getTime()); + } + } + + /** + * Specifies settings for a time zone. + * http://msdn.microsoft.com/en-us/library/windows/desktop/ms725481(v=vs.85).aspx + */ + public static class TIME_ZONE_INFORMATION extends Structure { + public LONG Bias; + public String StandardName; + public SYSTEMTIME StandardDate; + public LONG StandardBias; + public String DaylightName; + public SYSTEMTIME DaylightDate; + public LONG DaylightBias; + + public TIME_ZONE_INFORMATION() { + super(W32APITypeMapper.DEFAULT); } - public STARTUPINFO() { - cb = new DWORD(size()); + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "Bias", "StandardName", "StandardDate", "StandardBias", "DaylightName", "DaylightDate", "DaylightBias" }); } } - /** - * Contains information about a newly created process and its primary - * thread. It is used with the CreateProcess, CreateProcessAsUser, - * CreateProcessWithLogonW, or CreateProcessWithTokenW function. - */ - public static class PROCESS_INFORMATION extends Structure { + /** + * The lpBuffer parameter is a pointer to a PVOID pointer, and that the nSize + * parameter specifies the minimum number of TCHARs to allocate for an output + * message buffer. The function allocates a buffer large enough to hold the + * formatted message, and places a pointer to the allocated buffer at the address + * specified by lpBuffer. The caller should use the LocalFree function to free + * the buffer when it is no longer needed. + */ + int FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100; + /** + * Insert sequences in the message definition are to be ignored and passed through + * to the output buffer unchanged. This flag is useful for fetching a message for + * later formatting. If this flag is set, the Arguments parameter is ignored. + */ + int FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200; + /** + * The lpSource parameter is a pointer to a null-terminated message definition. + * The message definition may contain insert sequences, just as the message text + * in a message table resource may. Cannot be used with FORMAT_MESSAGE_FROM_HMODULE + * or FORMAT_MESSAGE_FROM_SYSTEM. + */ + int FORMAT_MESSAGE_FROM_STRING = 0x00000400; + /** + * The lpSource parameter is a module handle containing the message-table + * resource(s) to search. If this lpSource handle is NULL, the current process's + * application image file will be searched. Cannot be used with + * FORMAT_MESSAGE_FROM_STRING. + */ + int FORMAT_MESSAGE_FROM_HMODULE = 0x00000800; + /** + * The function should search the system message-table resource(s) for the + * requested message. If this flag is specified with FORMAT_MESSAGE_FROM_HMODULE, + * the function searches the system message table if the message is not found in + * the module specified by lpSource. Cannot be used with FORMAT_MESSAGE_FROM_STRING. + * If this flag is specified, an application can pass the result of the + * GetLastError function to retrieve the message text for a system-defined error. + */ + int FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000; + /** + * The Arguments parameter is not a va_list structure, but is a pointer to an array + * of values that represent the arguments. This flag cannot be used with 64-bit + * argument values. If you are using 64-bit values, you must use the va_list + * structure. + */ + int FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x00002000; + + /** + * The drive type cannot be determined. + */ + int DRIVE_UNKNOWN = 0; + /** + * The root path is invalid, for example, no volume is mounted at the path. + */ + int DRIVE_NO_ROOT_DIR = 1; + /** + * The drive is a type that has removable media, for example, a floppy drive + * or removable hard disk. + */ + int DRIVE_REMOVABLE = 2; + /** + * The drive is a type that cannot be removed, for example, a fixed hard drive. + */ + int DRIVE_FIXED = 3; + /** + * The drive is a remote (network) drive. + */ + int DRIVE_REMOTE = 4; + /** + * The drive is a CD-ROM drive. + */ + int DRIVE_CDROM = 5; + /** + * The drive is a RAM disk. + */ + int DRIVE_RAMDISK = 6; + + /** + * The OVERLAPPED structure contains information used in + * asynchronous (or overlapped) input and output (I/O). + */ + public static class OVERLAPPED extends Structure { + public ULONG_PTR Internal; + public ULONG_PTR InternalHigh; + public int Offset; + public int OffsetHigh; + public HANDLE hEvent; + + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "Internal", "InternalHigh", "Offset", "OffsetHigh", "hEvent" }); + } + } + + int INFINITE = 0xFFFFFFFF; + + /** + * Contains information about the current computer system. This includes the architecture and + * type of the processor, the number of processors in the system, the page size, and other such + * information. + */ + public static class SYSTEM_INFO extends Structure { + + /** Unnamed inner structure. */ + public static class PI extends Structure { + + public static class ByReference extends PI implements Structure.ByReference { + + } + + /** + * System's processor architecture. + * This value can be one of the following values: + * + * PROCESSOR_ARCHITECTURE_UNKNOWN + * PROCESSOR_ARCHITECTURE_INTEL + * PROCESSOR_ARCHITECTURE_IA64 + * PROCESSOR_ARCHITECTURE_AMD64 + */ + public WORD wProcessorArchitecture; + /** + * Reserved for future use. + */ + public WORD wReserved; + + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "wProcessorArchitecture", "wReserved" }); + } + } + + /** Unnamed inner union. */ + public static class UNION extends Union { + + public static class ByReference extends UNION implements Structure.ByReference { + + } + + /** + * An obsolete member that is retained for compatibility with Windows NT 3.5 and earlier. + * New applications should use the wProcessorArchitecture branch of the union. + * Windows Me/98/95: The system always sets this member to zero, the value defined + * for PROCESSOR_ARCHITECTURE_INTEL. + */ + public DWORD dwOemID; + /** + * Processor architecture (unnamed struct). + */ + public PI pi; + } + + /** + * Processor architecture (unnamed union). + */ + public UNION processorArchitecture; + /** + * Page size and the granularity of page protection and commitment. + */ + public DWORD dwPageSize; + /** + * Pointer to the lowest memory address accessible to applications and dynamic-link libraries (DLLs). + */ + public Pointer lpMinimumApplicationAddress; + /** + * Pointer to the highest memory address accessible to applications and DLLs. + */ + public Pointer lpMaximumApplicationAddress; + /** + * Mask representing the set of processors configured into the system. Bit 0 is processor 0; bit 31 is processor 31. + */ + public DWORD_PTR dwActiveProcessorMask; + /** + * Number of processors in the system. + */ + public DWORD dwNumberOfProcessors; + /** + * An obsolete member that is retained for compatibility with Windows NT 3.5 and Windows Me/98/95. + * Use the wProcessorArchitecture, wProcessorLevel, and wProcessorRevision members to determine + * the type of processor. + * PROCESSOR_INTEL_386 + * PROCESSOR_INTEL_486 + * PROCESSOR_INTEL_PENTIUM + */ + public DWORD dwProcessorType; + /** + * Granularity for the starting address at which virtual memory can be allocated. + */ + public DWORD dwAllocationGranularity; + /** + * System's architecture-dependent processor level. It should be used only for display purposes. + * To determine the feature set of a processor, use the IsProcessorFeaturePresent function. + * If wProcessorArchitecture is PROCESSOR_ARCHITECTURE_INTEL, wProcessorLevel is defined by the CPU vendor. + * If wProcessorArchitecture is PROCESSOR_ARCHITECTURE_IA64, wProcessorLevel is set to 1. + */ + public WORD wProcessorLevel; + /** + * Architecture-dependent processor revision. + */ + public WORD wProcessorRevision; + + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "processorArchitecture", "dwPageSize", "lpMinimumApplicationAddress", "lpMaximumApplicationAddress", "dwActiveProcessorMask", "dwNumberOfProcessors", "dwProcessorType", "dwAllocationGranularity", "wProcessorLevel", "wProcessorRevision"}); + } + } + + /** + * Contains information about the current state of both physical and virtual memory, including + * extended memory. The GlobalMemoryStatusEx function stores information in this structure. + */ + public static class MEMORYSTATUSEX extends Structure { + /** + * The size of the structure, in bytes. + */ + public DWORD dwLength; + /** + * A number between 0 and 100 that specifies the approximate percentage of physical memory + * that is in use (0 indicates no memory use and 100 indicates full memory use). + */ + public DWORD dwMemoryLoad; + /** + * The amount of actual physical memory, in bytes. + */ + public DWORDLONG ullTotalPhys; + /** + * The amount of physical memory currently available, in bytes. This is the amount of physical + * memory that can be immediately reused without having to write its contents to disk first. + * It is the sum of the size of the standby, free, and zero lists. + */ + public DWORDLONG ullAvailPhys; + /** + * The current committed memory limit for the system or the current process, whichever is smaller, in bytes. + */ + public DWORDLONG ullTotalPageFile; + /** + * The maximum amount of memory the current process can commit, in bytes. This value is equal to or smaller + * than the system-wide available commit value. + */ + public DWORDLONG ullAvailPageFile; + /** + * The size of the user-mode portion of the virtual address space of the calling process, in bytes. + */ + public DWORDLONG ullTotalVirtual; + /** + * The amount of unreserved and uncommitted memory currently in the user-mode portion of the + * virtual address space of the calling process, in bytes. + */ + public DWORDLONG ullAvailVirtual; + /** + * Reserved. This value is always 0. + */ + public DWORDLONG ullAvailExtendedVirtual; + + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "dwLength", "dwMemoryLoad", "ullTotalPhys", "ullAvailPhys", "ullTotalPageFile", "ullAvailPageFile", "ullTotalVirtual", "ullAvailVirtual", "ullAvailExtendedVirtual" }); + } + + public MEMORYSTATUSEX() { + dwLength = new DWORD(size()); + } + }; + + /** + * The SECURITY_ATTRIBUTES structure contains the security descriptor for an + * object and specifies whether the handle retrieved by specifying this + * structure is inheritable. This structure provides security settings for + * objects created by various functions, such as {@link Kernel32#CreateFile}, + * {@link Kernel32#CreatePipe}, or {@link Advapi32#RegCreateKeyEx}. + */ + public static class SECURITY_ATTRIBUTES extends Structure { + /** + * The size of the structure, in bytes. + */ + public DWORD dwLength; + + /** + * A pointer to a SECURITY_DESCRIPTOR structure that controls access to the object. + */ + public Pointer lpSecurityDescriptor; + + /** + * A Boolean value that specifies whether the returned handle is inherited when + * a new process is created + */ + public boolean bInheritHandle; + + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "dwLength", "lpSecurityDescriptor", "bInheritHandle" }); + } + + public SECURITY_ATTRIBUTES() { + dwLength = new DWORD(size()); + } + } + + /** + * Specifies the window station, desktop, standard handles, and appearance of the main + * window for a process at creation time. + */ + public static class STARTUPINFO extends Structure { + /** + * The size of the structure, in bytes. + */ + public DWORD cb; + + /** + * Reserved; must be NULL. + */ + public String lpReserved; + + /** + * The name of the desktop, or the name of both the desktop and window station for this process. + * A backslash in the string indicates that the string includes both the desktop and window + * station names. For more information, see Thread Connection to a Desktop. + */ + public String lpDesktop; + + /** + * For console processes, this is the title displayed in the title bar + * if a new console window is created. If NULL, the name of the + * executable file is used as the window title instead. This parameter + * must be NULL for GUI or console processes that do not create a new + * console window. + */ + public String lpTitle; + + /** + * If dwFlags specifies STARTF_USEPOSITION, this member is the x offset + * of the upper left corner of a window if a new window is created, in + * pixels. Otherwise, this member is ignored. + * + * The offset is from the upper left corner of the screen. For GUI + * processes, the specified position is used the first time the new + * process calls CreateWindow to create an overlapped window if the x + * parameter of CreateWindow is CW_USEDEFAULT. + */ + public DWORD dwX; + + /** + * If dwFlags specifies STARTF_USEPOSITION, this member is the y offset + * of the upper left corner of a window if a new window is created, in + * pixels. Otherwise, this member is ignored. + * + * The offset is from the upper left corner of the screen. For GUI + * processes, the specified position is used the first time the new + * process calls CreateWindow to create an overlapped window if the y + * parameter of CreateWindow is CW_USEDEFAULT. + */ + public DWORD dwY; + + /** + * If dwFlags specifies STARTF_USESIZE, this member is the width of the + * window if a new window is created, in pixels. Otherwise, this member + * is ignored. + * + * For GUI processes, this is used only the first time the new process + * calls CreateWindow to create an overlapped window if the nWidth + * parameter of CreateWindow is CW_USEDEFAULT. + */ + public DWORD dwXSize; + + /** + * If dwFlags specifies STARTF_USESIZE, this member is the height of the + * window if a new window is created, in pixels. Otherwise, this member + * is ignored. + * + * For GUI processes, this is used only the first time the new process + * calls CreateWindow to create an overlapped window if the nHeight + * parameter of CreateWindow is CW_USEDEFAULT. + */ + public DWORD dwYSize; + + /** + * If dwFlags specifies STARTF_USECOUNTCHARS, if a new console window is + * created in a console process, this member specifies the screen buffer + * width, in character columns. Otherwise, this member is ignored. + */ + public DWORD dwXCountChars; + + /** + * If dwFlags specifies STARTF_USECOUNTCHARS, if a new console window is + * created in a console process, this member specifies the screen buffer + * height, in character rows. Otherwise, this member is ignored. + */ + public DWORD dwYCountChars; + + /** + * If dwFlags specifies STARTF_USEFILLATTRIBUTE, this member is the + * initial text and background colors if a new console window is created + * in a console application. Otherwise, this member is ignored. + * + * This value can be any combination of the following values: + * FOREGROUND_BLUE, FOREGROUND_GREEN, FOREGROUND_RED, + * FOREGROUND_INTENSITY, BACKGROUND_BLUE, BACKGROUND_GREEN, + * BACKGROUND_RED, and BACKGROUND_INTENSITY. For example, the following + * combination of values produces red text on a white background: + * + * FOREGROUND_RED| BACKGROUND_RED| BACKGROUND_GREEN| BACKGROUND_BLUE + */ + public DWORD dwFillAttribute; + + /** + * A bit field that determines whether certain STARTUPINFO members are + * used when the process creates a window. + */ + public int dwFlags; + + /** + * If dwFlags specifies STARTF_USESHOWWINDOW, this member can be any of + * the values that can be specified in the nCmdShow parameter for the + * ShowWindow function, except for SW_SHOWDEFAULT. Otherwise, this + * member is ignored. + * + * For GUI processes, the first time ShowWindow is called, its nCmdShow + * parameter is ignored wShowWindow specifies the default value. In + * subsequent calls to ShowWindow, the wShowWindow member is used if the + * nCmdShow parameter of ShowWindow is set to SW_SHOWDEFAULT. + */ + public WORD wShowWindow; + + /** + * Reserved for use by the C Run-time; must be zero. + */ + public WORD cbReserved2; + + /** + * Reserved for use by the C Run-time; must be NULL. + */ + public ByteByReference lpReserved2; + + /** + * If dwFlags specifies STARTF_USESTDHANDLES, this member is the + * standard input handle for the process. If STARTF_USESTDHANDLES is not + * specified, the default for standard input is the keyboard buffer. + * + * If dwFlags specifies STARTF_USEHOTKEY, this member specifies a hotkey + * value that is sent as the wParam parameter of a WM_SETHOTKEY message + * to the first eligible top-level window created by the application + * that owns the process. If the window is created with the WS_POPUP + * window style, it is not eligible unless the WS_EX_APPWINDOW extended + * window style is also set. For more information, see CreateWindowEx. + * + * Otherwise, this member is ignored. + */ + public HANDLE hStdInput; + + /** + * If dwFlags specifies STARTF_USESTDHANDLES, this member is the + * standard output handle for the process. Otherwise, this member is + * ignored and the default for standard output is the console window's + * buffer. + */ + public HANDLE hStdOutput; + + /** + * If dwFlags specifies STARTF_USESTDHANDLES, this member is the + * standard error handle for the process. Otherwise, this member is + * ignored and the default for standard error is the console window's + * buffer. + */ + public HANDLE hStdError; + + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "cb", "lpReserved", "lpDesktop", "lpTitle", "dwX", "dwY", "dwXSize", "dwYSize", "dwXCountChars", "dwYCountChars", "dwFillAttribute", "dwFlags", "wShowWindow", "cbReserved2", "lpReserved2", "hStdInput", "hStdOutput", "hStdError" }); + } + + public STARTUPINFO() { + super(W32APITypeMapper.DEFAULT); + cb = new DWORD(size()); + } + } + + /** + * Contains information about a newly created process and its primary + * thread. It is used with the CreateProcess, CreateProcessAsUser, + * CreateProcessWithLogonW, or CreateProcessWithTokenW function. + */ + public static class PROCESS_INFORMATION extends Structure { + + /** + * A handle to the newly created process. The handle is used to specify + * the process in all functions that perform operations on the process + * object. + */ + public HANDLE hProcess; + + /** + * A handle to the primary thread of the newly created process. The + * handle is used to specify the thread in all functions that perform + * operations on the thread object. + */ + public HANDLE hThread; + + /** + * A value that can be used to identify a process. The value is valid + * from the time the process is created until all handles to the process + * are closed and the process object is freed; at this point, the + * identifier may be reused. + */ + public DWORD dwProcessId; + + /** + * A value that can be used to identify a thread. The value is valid + * from the time the thread is created until all handles to the thread + * are closed and the thread object is freed; at this point, the + * identifier may be reused. + */ + public DWORD dwThreadId; + + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "hProcess", "hThread", "dwProcessId", "dwThreadId" }); + } + + public static class ByReference extends PROCESS_INFORMATION implements Structure.ByReference { + public ByReference() { + } + + public ByReference(Pointer memory) { + super(memory); + } + } + + public PROCESS_INFORMATION() { + } + + public PROCESS_INFORMATION(Pointer memory) { + super(memory); + read(); + } + } + + /** + * If the file is to be moved to a different volume, the function simulates the move by using the CopyFile and DeleteFile functions. + * + * This value cannot be used with MOVEFILE_DELAY_UNTIL_REBOOT. + */ + int MOVEFILE_COPY_ALLOWED = 0x2; + + /** + * Reserved for future use. + */ + int MOVEFILE_CREATE_HARDLINK = 0x10; + + /** + * The system does not move the file until the operating system is restarted. The system moves the file immediately + * after AUTOCHK is executed, but before creating any paging files. Consequently, this parameter enables the + * function to delete paging files from previous startups. + * + * This value can be used only if the process is in the context of a user who belongs to the administrators group or + * the LocalSystem account. + * + * This value cannot be used with MOVEFILE_COPY_ALLOWED. + * + * Windows Server 2003 and Windows XP: For information about special situations where this functionality can fail, + * and a suggested workaround solution, see Files are not exchanged when Windows Server 2003 restarts if you use the + * MoveFileEx function to schedule a replacement for some files in the Help and Support Knowledge Base. + * + * Windows 2000: If you specify the MOVEFILE_DELAY_UNTIL_REBOOT flag for dwFlags, you cannot also prepend the file + * name that is specified by lpExistingFileName with "\\?". + */ + int MOVEFILE_DELAY_UNTIL_REBOOT = 0x4; + + /** + * The function fails if the source file is a link source, but the file cannot be tracked after the move. This + * situation can occur if the destination is a volume formatted with the FAT file system. + */ + int MOVEFILE_FAIL_IF_NOT_TRACKABLE = 0x20; + + /** + * If a file named lpNewFileName exists, the function replaces its contents with the contents of the + * lpExistingFileName file, provided that security requirements regarding access control lists (ACLs) are met. For + * more information, see the Remarks section of this topic. + * + * This value cannot be used if lpNewFileName or lpExistingFileName names a directory. + */ + int MOVEFILE_REPLACE_EXISTING = 0x1; + + /** + * The function does not return until the file is actually moved on the disk. + * + * Setting this value guarantees that a move performed as a copy and delete operation is flushed to disk before the + * function returns. The flush occurs at the end of the copy operation. + * + * This value has no effect if MOVEFILE_DELAY_UNTIL_REBOOT is set. + */ + int MOVEFILE_WRITE_THROUGH = 0x8; + + /** + * Represents a thread entry point local to this process, as a Callback. + */ + public interface THREAD_START_ROUTINE extends StdCallCallback{ + public DWORD apply( LPVOID lpParameter ); + } + + /** + * Represents a thread entry point in another process. Can only be expressed as a pointer, as + * the location has no meaning in the Java process. + */ + public class FOREIGN_THREAD_START_ROUTINE extends Structure { + LPVOID foreignLocation; + + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "foreignLocation" }); + } + } + + /** + * Specifies a type of computer name to be retrieved by the GetComputerNameEx function + */ + public static interface COMPUTER_NAME_FORMAT { + /** + * The NetBIOS name of the local computer or the cluster associated with the local + * computer. This name is limited to MAX_COMPUTERNAME_LENGTH + 1 characters and may + * be a truncated version of the DNS host name. For example, if the DNS host name is + * "corporate-mail-server", the NetBIOS name would be "corporate-mail-"". + */ + int ComputerNameNetBIOS = 0; + + /** + * The DNS name of the local computer or the cluster associated with the local computer. + */ + int ComputerNameDnsHostname = 1; + + /** + * The name of the DNS domain assigned to the local computer or the cluster associated + * with the local computer. + */ + int ComputerNameDnsDomain = 2; + + /** + * The fully qualified DNS name that uniquely identifies the local computer or the cluster + * associated with the local computer. This name is a combination of the DNS host name and + * the DNS domain name, using the form HostName.DomainName. For example, if the DNS host + * name is "corporate-mail-server" and the DNS domain name is "microsoft.com", + * the fully qualified DNS name is "corporate-mail-server.microsoft.com". + */ + int ComputerNameDnsFullyQualified = 3; + + /** + * The NetBIOS name of the local computer. On a cluster, this is the NetBIOS name of the + * local node on the cluster. + */ + int ComputerNamePhysicalNetBIOS = 4; + + /** + * The DNS host name of the local computer. On a cluster, this is the DNS host name of the + * local node on the cluster. + */ + int ComputerNamePhysicalDnsHostname = 5; + + /** + * The name of the DNS domain assigned to the local computer. On a cluster, this is the DNS + * domain of the local node on the cluster. + */ + int ComputerNamePhysicalDnsDomain = 6; + + /** + * The fully qualified DNS name that uniquely identifies the computer. On a cluster, this is + * the fully qualified DNS name of the local node on the cluster. The fully qualified DNS name + * is a combination of the DNS host name and the DNS domain name, using the form HostName.DomainName. + */ + int ComputerNamePhysicalDnsFullyQualified = 7; + + /** + * Note used - serves as an upper limit in case one wants to go through all the values + */ + int ComputerNameMax = 8; + } + + /** + * An application-defined callback function used with ReadEncryptedFileRaw. + * The system calls ExportCallback one or more times, each time with a block + * of the encrypted file's data, until it has received all of the file data. + * ExportCallback writes the encrypted file's data to another storage media, + * usually for purposes of backing up the file. + */ + public interface FE_EXPORT_FUNC extends StdCallCallback { + public DWORD callback(Pointer pbData, Pointer pvCallbackContext, + ULONG ulLength); + } + + /** + * An application-defined callback function used with WriteEncryptedFileRaw. + * The system calls ImportCallback one or more times, each time to retrieve a + * portion of a backup file's data. ImportCallback reads the data from a + * backup file sequentially and restores the data, and the system continues + * calling it until it has read all of the backup file data. + */ + public interface FE_IMPORT_FUNC extends StdCallCallback { + public DWORD callback(Pointer pbData, Pointer pvCallbackContext, + ULONGByReference ulLength); + } + + int PIPE_CLIENT_END=0x00000000; + int PIPE_SERVER_END=0x00000001; + + /* Pipe open mode values */ + int PIPE_ACCESS_DUPLEX=0x00000003; + int PIPE_ACCESS_INBOUND=0x00000001; + int PIPE_ACCESS_OUTBOUND=0x00000002; + + /* Pipe type values */ + int PIPE_TYPE_BYTE=0x00000000; + int PIPE_TYPE_MESSAGE=0x00000004; + + /* Pipe read modes */ + int PIPE_READMODE_BYTE=0x00000000; + int PIPE_READMODE_MESSAGE=0x00000002; + + /* Pipe wait modes */ + int PIPE_WAIT=0x00000000; + int PIPE_NOWAIT=0x00000001; + + int PIPE_ACCEPT_REMOTE_CLIENTS=0x00000000; + int PIPE_REJECT_REMOTE_CLIENTS=0x00000008; + + int PIPE_UNLIMITED_INSTANCES=255; + + /* Named pipe pre-defined timeout values */ + int NMPWAIT_USE_DEFAULT_WAIT=0x00000000; + int NMPWAIT_NOWAIT=0x00000001; + int NMPWAIT_WAIT_FOREVER=0xffffffff; + + + + /** + * + * Contains the time-out parameters for a communications device. The + * parameters determine the behavior of + * {@link Kernel32#ReadFile}, {@link Kernel32#WriteFile}, ReadFileEx, and + * WriteFileEx operations on the device. + *
    + * + * Remarks
    + * If an application sets ReadIntervalTimeout and ReadTotalTimeoutMultiplier + * to MAXDWORD and sets ReadTotalTimeoutConstant to a value greater than + * zero and less than MAXDWORD, one of the following occurs when the + * ReadFile function is called: + *
  • If there are any bytes in the input buffer, ReadFile returns + * immediately with the bytes in the buffer.
  • + *
  • If there are no bytes in the input buffer, ReadFile waits until a + * byte arrives and then returns immediately.
  • + *
  • If no bytes arrive within the time specified by + * ReadTotalTimeoutConstant, ReadFile times out.
  • + * + * @author Markus + */ + public static class COMMTIMEOUTS extends Structure { + public static final List FIELDS = createFieldsOrder("ReadIntervalTimeout", "ReadTotalTimeoutMultiplier", + "ReadTotalTimeoutConstant", "WriteTotalTimeoutMultiplier", "WriteTotalTimeoutConstant"); + + /** + * + * The maximum time allowed to elapse before the arrival of the next + * byte on the communications line, in milliseconds. If the interval + * between the arrival of any two bytes exceeds this amount, the + * {@link Kernel32#ReadFile} + * operation is completed and any buffered data is returned. A value of + * zero indicates that interval time-outs are not used. + * + * A value of MAXDWORD, combined with zero values for both the + * {@link COMMTIMEOUTS#ReadTotalTimeoutConstant} and + * {@link COMMTIMEOUTS#ReadTotalTimeoutMultiplier} members, specifies + * that the read operation is to return immediately with the bytes that + * have already been received, even if no bytes have been received. + * + */ + public DWORD ReadIntervalTimeout; + + /** + * The multiplier used to calculate the total time-out period for read + * operations, in milliseconds. For each read operation, this value is + * multiplied by the requested number of bytes to be read. + */ + public DWORD ReadTotalTimeoutMultiplier; + + /** + * A constant used to calculate the total time-out period for read + * operations, in milliseconds. For each read operation, this value is + * added to the product of the + * {@link COMMTIMEOUTS#ReadTotalTimeoutMultiplier} member and the + * requested number of bytes. + * + * A value of zero for both the + * {@link COMMTIMEOUTS#ReadTotalTimeoutMultiplier} and + * {@link COMMTIMEOUTS#ReadTotalTimeoutConstant} members indicates that + * total time-outs are not used for read operations. + */ + public DWORD ReadTotalTimeoutConstant; + + /** + * The multiplier used to calculate the total time-out period for write + * operations, in milliseconds. For each write operation, this value is + * multiplied by the number of bytes to be written. + */ + public DWORD WriteTotalTimeoutMultiplier; + + /** + * A constant used to calculate the total time-out period for write + * operations, in milliseconds. For each write operation, this value is + * added to the product of the + * {@link COMMTIMEOUTS#WriteTotalTimeoutMultiplier} member and the + * number of bytes to be written. + * + * A value of zero for both the + * {@link COMMTIMEOUTS#WriteTotalTimeoutMultiplier} and + * {@link COMMTIMEOUTS#WriteTotalTimeoutConstant} members indicates that + * total time-outs are not used for write operations. + * + */ + public DWORD WriteTotalTimeoutConstant; + + @Override + protected List getFieldOrder() { + return FIELDS; + } + } + + /** + * Defines the control setting for a serial communications device. + */ + public static class DCB extends Structure { + + /** + * Type is used to handle the bitfield of the DBC structure. + */ + public static class DCBControllBits extends DWORD { + private static final long serialVersionUID = 8574966619718078579L; + + @Override + public String toString() { + final StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append('<'); + stringBuilder.append("fBinary:1="); + stringBuilder.append(getfBinary() ? '1' : '0'); + stringBuilder.append(", fParity:1="); + stringBuilder.append(getfParity() ? '1' : '0'); + stringBuilder.append(", fOutxCtsFlow:1="); + stringBuilder.append(getfOutxCtsFlow() ? '1' : '0'); + stringBuilder.append(", fOutxDsrFlow:1="); + stringBuilder.append(getfOutxDsrFlow() ? '1' : '0'); + stringBuilder.append(", fDtrControl:2="); + stringBuilder.append(getfDtrControl()); + stringBuilder.append(", fDsrSensitivity:1="); + stringBuilder.append(getfDsrSensitivity() ? '1' : '0'); + stringBuilder.append(", fTXContinueOnXoff:1="); + stringBuilder.append(getfTXContinueOnXoff() ? '1' : '0'); + stringBuilder.append(", fOutX:1="); + stringBuilder.append(getfOutX() ? '1' : '0'); + stringBuilder.append(", fInX:1="); + stringBuilder.append(getfInX() ? '1' : '0'); + stringBuilder.append(", fErrorChar:1="); + stringBuilder.append(getfErrorChar() ? '1' : '0'); + stringBuilder.append(", fNull:1="); + stringBuilder.append(getfNull() ? '1' : '0'); + stringBuilder.append(", fRtsControl:2="); + stringBuilder.append(getfRtsControl()); + stringBuilder.append(", fAbortOnError:1="); + stringBuilder.append(getfAbortOnError() ? '1' : '0'); + stringBuilder.append(", fDummy2:17="); + stringBuilder.append(getfDummy2()); + stringBuilder.append('>'); + return stringBuilder.toString(); + } + + public boolean getfAbortOnError() { + return (this.intValue() & (0x01 << 14)) != 0x00; + } + + public boolean getfBinary() { + return (this.intValue() & 0x01) != 0x00; + } + + public boolean getfDsrSensitivity() { + return (this.intValue() & (0x01 << 6)) != 0x00; + } + + public int getfDtrControl() { + return (this.intValue() >>> 4) & 0x03; + } + + public boolean getfErrorChar() { + return (this.intValue() & (0x01 << 10)) != 0x00; + } + + public boolean getfInX() { + return (this.intValue() & (0x01 << 9)) != 0x00; + } + + public boolean getfNull() { + return (this.intValue() & (0x01 << 11)) != 0x00; + } + + public boolean getfOutX() { + return (this.intValue() & (0x01 << 8)) != 0x00; + } + + public boolean getfOutxCtsFlow() { + return (this.intValue() & (0x01 << 2)) != 0x00; + } + + public boolean getfOutxDsrFlow() { + return (this.intValue() & (0x01 << 3)) != 0x00; + } + + public boolean getfParity() { + return (this.intValue() & (0x01 << 1)) != 0x00; + } + + public int getfRtsControl() { + return (this.intValue() >>> 12) & 0x03; + } + + public int getfDummy2() { + return (this.intValue()>>>15) & 0x1FFFF; + } + + public boolean getfTXContinueOnXoff() { + return (this.intValue() & (0x01 << 7)) != 0x00; + } + + /** + * If this member is TRUE, the driver terminates all read and write + * operations with an error status if an error occurs.
    + * The driver will not accept any further communications operations + * until the application has acknowledged the error by calling the + * ClearCommError function. + * + * @param fAbortOnError + */ + public void setfAbortOnError(boolean fAbortOnError) { + int tmp = leftShiftMask(fAbortOnError ? 1 : 0, (byte)14, 0x01, this.intValue()); + this.setValue(tmp); + } + + /** + * If this member is TRUE, binary mode is enabled.
    + * Windows does not support nonbinary mode transfers, so this member + * must be TRUE. + * + * @param fBinary + */ + public void setfBinary(boolean fBinary) { + int tmp = leftShiftMask(fBinary ? 1 : 0, (byte)0, 0x01, this.intValue()); + this.setValue(tmp); + } + + /** + * If this member is TRUE, the communications driver is sensitive to the + * state of the DSR signal.
    + * The driver ignores any bytes received, unless the DSR modem input + * line is high. + * + * @param fDsrSensitivity + */ + public void setfDsrSensitivity(boolean fDsrSensitivity) { + int tmp = leftShiftMask(fDsrSensitivity ? 1 : 0, (byte)6, 0x01, this.intValue()); + this.setValue(tmp); + } + + /** + * The DTR (data-terminal-ready) flow control. This member can be one of + * the following values. + *
  • {@link WinBase#DTR_CONTROL_DISABLE}
  • + *
  • {@link WinBase#DTR_CONTROL_ENABLE}
  • + *
  • {@link WinBase#DTR_CONTROL_HANDSHAKE}
  • + * + * @param fOutxDsrFlow + * value to set + */ + public void setfDtrControl(int fOutxDsrFlow) { + int tmp = leftShiftMask(fOutxDsrFlow, (byte)4, 0x03, this.intValue()); + this.setValue(tmp); + } + + /** + * Indicates whether bytes received with parity errors are replaced with + * the character specified by the ErrorChar member.
    + * If this member is TRUE and the fParity member is TRUE, replacement + * occurs. + * + * @param fErrorChar + */ + public void setfErrorChar(boolean fErrorChar) { + int tmp = leftShiftMask(fErrorChar ? 1 : 0, (byte)10, 0x01, this.intValue()); + this.setValue(tmp); + } + + /** + * Indicates whether XON/XOFF flow control is used during reception.
    + * If this member is TRUE, the XoffChar character is sent when the input + * buffer comes within XoffLim bytes of being full, and the XonChar + * character is sent when the input buffer comes within XonLim bytes of + * being empty. + * + * @param fInX + */ + public void setfInX(boolean fInX) { + int tmp = leftShiftMask(fInX ? 1 : 0, (byte)9, 0x01, this.intValue()); + this.setValue(tmp); + } + + /** + * If this member is TRUE, null bytes are discarded when received. + * + * @param fNull + */ + public void setfNull(boolean fNull) { + int tmp = leftShiftMask(fNull ? 1 : 0, (byte)11, 0x01, this.intValue()); + this.setValue(tmp); + } + + /** + * Indicates whether XON/XOFF flow control is used during transmission. + *
    + * If this member is TRUE, transmission stops when the XoffChar + * character is received and starts again when the XonChar character is + * received. + * + * @param fOutX + */ + public void setfOutX(boolean fOutX) { + int tmp = leftShiftMask(fOutX ? 1 : 0, (byte)8, 0x01, this.intValue()); + this.setValue(tmp); + } + + /** + * If this member is TRUE, the CTS (clear-to-send) signal is monitored + * for output flow control.
    + * If this member is TRUE and CTS is turned off, output is suspended + * until CTS is sent again. + * + * @param fOutxCtsFlow + */ + public void setfOutxCtsFlow(boolean fOutxCtsFlow) { + int tmp = leftShiftMask(fOutxCtsFlow ? 1 : 0, (byte)2, 0x01, this.intValue()); + this.setValue(tmp); + } + + /** + * If this member is TRUE, the DSR (data-set-ready) signal is monitored + * for output flow control.
    + * If this member is TRUE and DSR is turned off, output is suspended + * until DSR is sent again. + * + * @param fOutxDsrFlow + */ + public void setfOutxDsrFlow(boolean fOutxDsrFlow) { + int tmp = leftShiftMask(fOutxDsrFlow ? 1 : 0, (byte)3, 0x01, this.intValue()); + this.setValue(tmp); + } + + /** + * If this member is TRUE, parity checking is performed and errors are + * reported. + * + * @param fParity + */ + public void setfParity(boolean fParity) { + int tmp = leftShiftMask(fParity ? 1 : 0, (byte)1, 0x01, this.intValue()); + this.setValue(tmp); + } + + /** + * + * The RTS (request-to-send) flow control. This member can be one of the + * following values. + *
  • {@link WinBase#RTS_CONTROL_DISABLE}
  • + *
  • {@link WinBase#RTS_CONTROL_ENABLE}
  • + *
  • {@link WinBase#RTS_CONTROL_HANDSHAKE}
  • + *
  • {@link WinBase#RTS_CONTROL_TOGGLE}
  • + * + * @param fRtsControl + */ + public void setfRtsControl(int fRtsControl) { + int tmp = leftShiftMask(fRtsControl, (byte)12, 0x03, this.intValue()); + this.setValue(tmp); + } + + /** + * If this member is TRUE, transmission continues after the input buffer + * has come within XoffLim bytes of being full and the driver has + * transmitted the XoffChar character to stop receiving bytes.
    + * If this member is FALSE, transmission does not continue until the + * input buffer is within XonLim bytes of being empty and the driver has + * transmitted the XonChar character to resume reception. + * + * @param fTXContinueOnXoff + */ + public void setfTXContinueOnXoff(boolean fTXContinueOnXoff) { + int tmp = leftShiftMask(fTXContinueOnXoff ? 1 : 0, (byte)7, 0x01, this.intValue()); + this.setValue(tmp); + } + + + private static int leftShiftMask(int valuetoset, byte shift, int mask, int storage) { + int tmp = storage; + tmp &= ~(mask << shift); + tmp |= ((valuetoset & mask) << shift); + return tmp; + } + } + /** + * The length of the structure, in bytes. The caller must set this + * member to sizeof(DCB). + */ + public DWORD DCBlength; + + /** + * + * The baud rate at which the communications device operates. This + * member can be an actual baud rate value, or one of the following + * indexes. + *
  • {@link WinBase#CBR_110}
  • + *
  • {@link WinBase#CBR_300}
  • + *
  • {@link WinBase#CBR_600}
  • + *
  • {@link WinBase#CBR_1200}
  • + *
  • {@link WinBase#CBR_2400}
  • + *
  • {@link WinBase#CBR_4800}
  • + *
  • {@link WinBase#CBR_9600}
  • + *
  • {@link WinBase#CBR_14400}
  • + *
  • {@link WinBase#CBR_19200}
  • + *
  • {@link WinBase#CBR_38400}
  • + *
  • {@link WinBase#CBR_56000}
  • + *
  • {@link WinBase#CBR_128000}
  • + *
  • {@link WinBase#CBR_256000}
  • + * + */ + public DWORD BaudRate; + + /** + * Contains all the bit wise setting entries. + */ + public DCBControllBits controllBits; + + /** + * Reserved; must be zero. + */ + public WORD wReserved; + + /** + * The minimum number of bytes in use allowed in the input buffer before + * flow control is activated to allow transmission by the sender. This + * assumes that either XON/XOFF, RTS, or DTR input flow control is + * specified in the fInX, fRtsControl, or fDtrControl members. + */ + public WORD XonLim; + + /** + * The minimum number of free bytes allowed in the input buffer before + * flow control is activated to inhibit the sender. Note that the sender + * may transmit characters after the flow control signal has been + * activated, so this value should never be zero. This assumes that + * either XON/XOFF, RTS, or DTR input flow control is specified in the + * fInX, fRtsControl, or fDtrControl members. The maximum number of + * bytes in use allowed is calculated by subtracting this value from the + * size, in bytes, of the input buffer. + */ + public WORD XoffLim; + + /** + * The number of bits in the bytes transmitted and received. + */ + public BYTE ByteSize; + + /** + * + * The parity scheme to be used. This member can be one of the following + * values. + *
  • {@link WinBase#EVENPARITY}
  • + *
  • {@link WinBase#ODDPARITY}
  • + *
  • {@link WinBase#NOPARITY}
  • + *
  • {@link WinBase#SPACEPARITY}
  • + *
  • {@link WinBase#MARKPARITY}
  • + */ + public BYTE Parity; + + /** + * The number of stop bits to be used. This member can be one of the + * following values. + *
  • {@link WinBase#ONESTOPBIT}
  • + *
  • {@link WinBase#ONE5STOPBITS}
  • + *
  • {@link WinBase#TWOSTOPBITS}
  • + */ + public BYTE StopBits; - /** - * A handle to the newly created process. The handle is used to specify - * the process in all functions that perform operations on the process - * object. + /** + * The value of the XON character for both transmission and reception. */ - public HANDLE hProcess; - + public char XonChar; + /** - * A handle to the primary thread of the newly created process. The - * handle is used to specify the thread in all functions that perform - * operations on the thread object. + * The value of the XOFF character for both transmission and reception. */ - public HANDLE hThread; + public char XoffChar; /** - * A value that can be used to identify a process. The value is valid - * from the time the process is created until all handles to the process - * are closed and the process object is freed; at this point, the - * identifier may be reused. + * The value of the character used to replace bytes received with a + * parity error. */ - public DWORD dwProcessId; + public char ErrorChar; /** - * A value that can be used to identify a thread. The value is valid - * from the time the thread is created until all handles to the thread - * are closed and the thread object is freed; at this point, the - * identifier may be reused. + * The value of the character used to signal the end of data. */ - public DWORD dwThreadId; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "hProcess", "hThread", "dwProcessId", "dwThreadId" }); - } + public char EofChar; - public static class ByReference extends PROCESS_INFORMATION implements Structure.ByReference { - public ByReference() { - } + /** + * The value of the character used to signal an event. + */ + public char EvtChar; - public ByReference(Pointer memory) { - super(memory); - } - } + /** + * Reserved; do not use. + */ + public WORD wReserved1; - public PROCESS_INFORMATION() { + public DCB() { + DCBlength = new DWORD(size()); } - public PROCESS_INFORMATION(Pointer memory) { - super(memory); - read(); + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "DCBlength", "BaudRate", "controllBits", "wReserved", "XonLim", + "XoffLim", "ByteSize", "Parity", "StopBits", "XonChar", "XoffChar", "ErrorChar", "EofChar", + "EvtChar", "wReserved1" }); } } /** - * If the file is to be moved to a different volume, the function simulates the move by using the CopyFile and DeleteFile functions. - * - * This value cannot be used with MOVEFILE_DELAY_UNTIL_REBOOT. + * No parity. */ - int MOVEFILE_COPY_ALLOWED = 0x2; + int NOPARITY = 0; /** - * Reserved for future use. + * Odd parity. */ - int MOVEFILE_CREATE_HARDLINK = 0x10; + int ODDPARITY = 1; /** - * The system does not move the file until the operating system is restarted. The system moves the file immediately - * after AUTOCHK is executed, but before creating any paging files. Consequently, this parameter enables the - * function to delete paging files from previous startups. - * - * This value can be used only if the process is in the context of a user who belongs to the administrators group or - * the LocalSystem account. - * - * This value cannot be used with MOVEFILE_COPY_ALLOWED. - * - * Windows Server 2003 and Windows XP: For information about special situations where this functionality can fail, - * and a suggested workaround solution, see Files are not exchanged when Windows Server 2003 restarts if you use the - * MoveFileEx function to schedule a replacement for some files in the Help and Support Knowledge Base. - * - * Windows 2000: If you specify the MOVEFILE_DELAY_UNTIL_REBOOT flag for dwFlags, you cannot also prepend the file - * name that is specified by lpExistingFileName with "\\?". + * Even parity. */ - int MOVEFILE_DELAY_UNTIL_REBOOT = 0x4; + int EVENPARITY = 2; /** - * The function fails if the source file is a link source, but the file cannot be tracked after the move. This - * situation can occur if the destination is a volume formatted with the FAT file system. + * Mark parity. */ - int MOVEFILE_FAIL_IF_NOT_TRACKABLE = 0x20; + int MARKPARITY = 3; /** - * If a file named lpNewFileName exists, the function replaces its contents with the contents of the - * lpExistingFileName file, provided that security requirements regarding access control lists (ACLs) are met. For - * more information, see the Remarks section of this topic. - * - * This value cannot be used if lpNewFileName or lpExistingFileName names a directory. + * Space parity. */ - int MOVEFILE_REPLACE_EXISTING = 0x1; + int SPACEPARITY = 4; /** - * The function does not return until the file is actually moved on the disk. - * - * Setting this value guarantees that a move performed as a copy and delete operation is flushed to disk before the - * function returns. The flush occurs at the end of the copy operation. - * - * This value has no effect if MOVEFILE_DELAY_UNTIL_REBOOT is set. + * 1 stop bit. */ - int MOVEFILE_WRITE_THROUGH = 0x8; + int ONESTOPBIT = 0; /** - * Represents a thread entry point local to this process, as a Callback. + * 1.5 stop bits. */ - public interface THREAD_START_ROUTINE extends Callback{ - public DWORD apply( LPVOID lpParameter ); - } - + int ONE5STOPBITS = 1; /** - * Represents a thread entry point in another process. Can only be expressed as a pointer, as - * the location has no meaning in the Java process. + * 2 stop bits. */ - public class FOREIGN_THREAD_START_ROUTINE extends Structure { - LPVOID foreignLocation; + int TWOSTOPBITS = 2; + /** + * 110 bps. + */ + int CBR_110 = 110; + /** + * 300 bps. + */ + int CBR_300 = 300; + /** + * 600 bps. + */ + int CBR_600 = 600; + /** + * 1200 bps. + */ + int CBR_1200 = 1200; + /** + * 2400 bps. + */ + int CBR_2400 = 2400; + /** + * 4800 bps. + */ + int CBR_4800 = 4800; + /** + * 9600 bps. + */ + int CBR_9600 = 9600; + /** + * 14400 bps. + */ + int CBR_14400 = 14400; + /** + * 19200 bps. + */ + int CBR_19200 = 19200; + /** + * 38400 bps. + */ + int CBR_38400 = 38400; + /** + * 56000 bps. + */ + int CBR_56000 = 56000; - @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "foreignLocation" }); - } - } - /** - * Specifies a type of computer name to be retrieved by the GetComputerNameEx function + * 128000 bps. */ - public static interface COMPUTER_NAME_FORMAT { - /** - * The NetBIOS name of the local computer or the cluster associated with the local - * computer. This name is limited to MAX_COMPUTERNAME_LENGTH + 1 characters and may - * be a truncated version of the DNS host name. For example, if the DNS host name is - * "corporate-mail-server", the NetBIOS name would be "corporate-mail-"". - */ - int ComputerNameNetBIOS = 0; - - /** - * The DNS name of the local computer or the cluster associated with the local computer. - */ - int ComputerNameDnsHostname = 1; - - /** - * The name of the DNS domain assigned to the local computer or the cluster associated - * with the local computer. - */ - int ComputerNameDnsDomain = 2; - - /** - * The fully qualified DNS name that uniquely identifies the local computer or the cluster - * associated with the local computer. This name is a combination of the DNS host name and - * the DNS domain name, using the form HostName.DomainName. For example, if the DNS host - * name is "corporate-mail-server" and the DNS domain name is "microsoft.com", - * the fully qualified DNS name is "corporate-mail-server.microsoft.com". - */ - int ComputerNameDnsFullyQualified = 3; - - /** - * The NetBIOS name of the local computer. On a cluster, this is the NetBIOS name of the - * local node on the cluster. - */ - int ComputerNamePhysicalNetBIOS = 4; - - /** - * The DNS host name of the local computer. On a cluster, this is the DNS host name of the - * local node on the cluster. - */ - int ComputerNamePhysicalDnsHostname = 5; - - /** - * The name of the DNS domain assigned to the local computer. On a cluster, this is the DNS - * domain of the local node on the cluster. - */ - int ComputerNamePhysicalDnsDomain = 6; - - /** - * The fully qualified DNS name that uniquely identifies the computer. On a cluster, this is - * the fully qualified DNS name of the local node on the cluster. The fully qualified DNS name - * is a combination of the DNS host name and the DNS domain name, using the form HostName.DomainName. - */ - int ComputerNamePhysicalDnsFullyQualified = 7; - - /** - * Note used - serves as an upper limit in case one wants to go through all the values - */ - int ComputerNameMax = 8; - } + int CBR_128000 = 128000; /** - * An application-defined callback function used with ReadEncryptedFileRaw. - * The system calls ExportCallback one or more times, each time with a block - * of the encrypted file's data, until it has received all of the file data. - * ExportCallback writes the encrypted file's data to another storage media, - * usually for purposes of backing up the file. + * 256000 bps. */ - public interface FE_EXPORT_FUNC extends Callback { - public DWORD callback(ByteByReference pbData, Pointer pvCallbackContext, - ULONG ulLength); - } + int CBR_256000 = 256000; /** - * An application-defined callback function used with WriteEncryptedFileRaw. - * The system calls ImportCallback one or more times, each time to retrieve a - * portion of a backup file's data. ImportCallback reads the data from a - * backup file sequentially and restores the data, and the system continues - * calling it until it has read all of the backup file data. + * Disables the DTR line when the device is opened and leaves it disabled. */ - public interface FE_IMPORT_FUNC extends Callback { - public DWORD callback(ByteByReference pbData, Pointer pvCallbackContext, - ULONGByReference ulLength); - } - - int PIPE_CLIENT_END=0x00000000; - int PIPE_SERVER_END=0x00000001; + int DTR_CONTROL_DISABLE = 0; - /* Pipe open mode values */ - int PIPE_ACCESS_DUPLEX=0x00000003; - int PIPE_ACCESS_INBOUND=0x00000001; - int PIPE_ACCESS_OUTBOUND=0x00000002; - - /* Pipe type values */ - int PIPE_TYPE_BYTE=0x00000000; - int PIPE_TYPE_MESSAGE=0x00000004; - - /* Pipe read modes */ - int PIPE_READMODE_BYTE=0x00000000; - int PIPE_READMODE_MESSAGE=0x00000002; - - /* Pipe wait modes */ - int PIPE_WAIT=0x00000000; - int PIPE_NOWAIT=0x00000001; - - int PIPE_ACCEPT_REMOTE_CLIENTS=0x00000000; - int PIPE_REJECT_REMOTE_CLIENTS=0x00000008; - - int PIPE_UNLIMITED_INSTANCES=255; - - /* Named pipe pre-defined timeout values */ - int NMPWAIT_USE_DEFAULT_WAIT=0x00000000; - int NMPWAIT_NOWAIT=0x00000001; - int NMPWAIT_WAIT_FOREVER=0xffffffff; - + /** + * Enables the DTR line when the device is opened and leaves it on. + */ + int DTR_CONTROL_ENABLE = 1; + + /** + * Enables DTR handshaking.
    + * If handshaking is enabled, it is an error for the application to adjust + * the line by using the EscapeCommFunction function. + */ + int DTR_CONTROL_HANDSHAKE = 2; + + /** + * Disables the RTS line when the device is opened and leaves it disabled. + */ + int RTS_CONTROL_DISABLE = 0; + + /** + * Enables the RTS line when the device is opened and leaves it on. + */ + int RTS_CONTROL_ENABLE = 1; + + /** + * Enables RTS handshaking.
    + * The driver raises the RTS line when the "type-ahead" (input) buffer is + * less than one-half full and lowers the RTS line when the buffer is more + * than three-quarters full.
    + * If handshaking is enabled, it is an error for the application to adjust + * the line by using the EscapeCommFunction function. + */ + int RTS_CONTROL_HANDSHAKE = 2; + /** + * Specifies that the RTS line will be high if bytes are available for + * transmission.
    + * After all buffered bytes have been sent, the RTS line will be low. + */ + int RTS_CONTROL_TOGGLE = 3;; - /** - * - * Contains the time-out parameters for a communications device. The - * parameters determine the behavior of - * {@link Kernel32#ReadFile(com.sun.jna.platform.win32.WinNT.HANDLE, java.nio.Buffer, int, com.sun.jna.ptr.IntByReference, com.sun.jna.platform.win32.WinBase.OVERLAPPED)} - * , {@link Kernel32#WriteFile(com.sun.jna.platform.win32.WinNT.HANDLE, - * byte[], int, com.sun.jna.ptr.IntByReference, - * com.sun.jna.platform.win32.WinBase.OVERLAPPED))}, ReadFileEx, and - * WriteFileEx operations on the device.
    - *
    - * - * Remarks
    - * If an application sets ReadIntervalTimeout and ReadTotalTimeoutMultiplier - * to MAXDWORD and sets ReadTotalTimeoutConstant to a value greater than - * zero and less than MAXDWORD, one of the following occurs when the - * ReadFile function is called: - *
  • If there are any bytes in the input buffer, ReadFile returns - * immediately with the bytes in the buffer.
  • - *
  • If there are no bytes in the input buffer, ReadFile waits until a - * byte arrives and then returns immediately.
  • - *
  • If no bytes arrive within the time specified by - * ReadTotalTimeoutConstant, ReadFile times out.
  • - * - * @author Markus - * - */ - public static class COMMTIMEOUTS extends Structure { - /** - * - * The maximum time allowed to elapse before the arrival of the next - * byte on the communications line, in milliseconds. If the interval - * between the arrival of any two bytes exceeds this amount, the - * {@link Kernel32#ReadFile(com.sun.jna.platform.win32.WinNT.HANDLE, java.nio.Buffer, int, com.sun.jna.ptr.IntByReference, com.sun.jna.platform.win32.WinBase.OVERLAPPED)} - * operation is completed and any buffered data is returned. A value of - * zero indicates that interval time-outs are not used. - * - * A value of MAXDWORD, combined with zero values for both the - * {@link COMMTIMEOUTS#ReadTotalTimeoutConstant} and - * {@link COMMTIMEOUTS#ReadTotalTimeoutMultiplier} members, specifies - * that the read operation is to return immediately with the bytes that - * have already been received, even if no bytes have been received. - * - */ - public DWORD ReadIntervalTimeout; - - /** - * The multiplier used to calculate the total time-out period for read - * operations, in milliseconds. For each read operation, this value is - * multiplied by the requested number of bytes to be read. - */ - public DWORD ReadTotalTimeoutMultiplier; - - /** - * A constant used to calculate the total time-out period for read - * operations, in milliseconds. For each read operation, this value is - * added to the product of the - * {@link COMMTIMEOUTS#ReadTotalTimeoutMultiplier} member and the - * requested number of bytes. - * - * A value of zero for both the - * {@link COMMTIMEOUTS#ReadTotalTimeoutMultiplier} and - * {@link COMMTIMEOUTS#ReadTotalTimeoutConstant} members indicates that - * total time-outs are not used for read operations. - */ - public DWORD ReadTotalTimeoutConstant; - - /** - * The multiplier used to calculate the total time-out period for write - * operations, in milliseconds. For each write operation, this value is - * multiplied by the number of bytes to be written. - */ - public DWORD WriteTotalTimeoutMultiplier; - - /** - * A constant used to calculate the total time-out period for write - * operations, in milliseconds. For each write operation, this value is - * added to the product of the - * {@link COMMTIMEOUTS#WriteTotalTimeoutMultiplier} member and the - * number of bytes to be written. - * - * A value of zero for both the - * {@link COMMTIMEOUTS#WriteTotalTimeoutMultiplier} and - * {@link COMMTIMEOUTS#WriteTotalTimeoutConstant} members indicates that - * total time-outs are not used for write operations. - * - */ - public DWORD WriteTotalTimeoutConstant; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "ReadIntervalTimeout", "ReadTotalTimeoutMultiplier", - "ReadTotalTimeoutConstant", "WriteTotalTimeoutMultiplier", "WriteTotalTimeoutConstant" }); - } - } - - - - /** - * Defines the control setting for a serial communications device. - */ - public static class DCB extends Structure { - - /** - * Type is used to handle the bitfield of the DBC structure. - */ - public static class DCBControllBits extends DWORD { - private static final long serialVersionUID = 8574966619718078579L; - - @Override - public String toString() { - final StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.append('<'); - stringBuilder.append("fBinary:1="); - stringBuilder.append(getfBinary() ? '1' : '0'); - stringBuilder.append(", fParity:1="); - stringBuilder.append(getfParity() ? '1' : '0'); - stringBuilder.append(", fOutxCtsFlow:1="); - stringBuilder.append(getfOutxCtsFlow() ? '1' : '0'); - stringBuilder.append(", fOutxDsrFlow:1="); - stringBuilder.append(getfOutxDsrFlow() ? '1' : '0'); - stringBuilder.append(", fDtrControl:2="); - stringBuilder.append(getfDtrControl()); - stringBuilder.append(", fDsrSensitivity:1="); - stringBuilder.append(getfDsrSensitivity() ? '1' : '0'); - stringBuilder.append(", fTXContinueOnXoff:1="); - stringBuilder.append(getfTXContinueOnXoff() ? '1' : '0'); - stringBuilder.append(", fOutX:1="); - stringBuilder.append(getfOutX() ? '1' : '0'); - stringBuilder.append(", fInX:1="); - stringBuilder.append(getfInX() ? '1' : '0'); - stringBuilder.append(", fErrorChar:1="); - stringBuilder.append(getfErrorChar() ? '1' : '0'); - stringBuilder.append(", fNull:1="); - stringBuilder.append(getfNull() ? '1' : '0'); - stringBuilder.append(", fRtsControl:2="); - stringBuilder.append(getfRtsControl()); - stringBuilder.append(", fAbortOnError:1="); - stringBuilder.append(getfAbortOnError() ? '1' : '0'); - stringBuilder.append(", fDummy2:17="); - stringBuilder.append(getfDummy2()); - stringBuilder.append('>'); - return stringBuilder.toString(); - } - - public boolean getfAbortOnError() { - return (this.intValue() & (0x01 << 14)) != 0x00; - } - - public boolean getfBinary() { - return (this.intValue() & 0x01) != 0x00; - } - - public boolean getfDsrSensitivity() { - return (this.intValue() & (0x01 << 6)) != 0x00; - } - - public int getfDtrControl() { - return (this.intValue() >>> 4) & 0x03; - } - - public boolean getfErrorChar() { - return (this.intValue() & (0x01 << 10)) != 0x00; - } - - public boolean getfInX() { - return (this.intValue() & (0x01 << 9)) != 0x00; - } - - public boolean getfNull() { - return (this.intValue() & (0x01 << 11)) != 0x00; - } - - public boolean getfOutX() { - return (this.intValue() & (0x01 << 8)) != 0x00; - } - - public boolean getfOutxCtsFlow() { - return (this.intValue() & (0x01 << 2)) != 0x00; - } - - public boolean getfOutxDsrFlow() { - return (this.intValue() & (0x01 << 3)) != 0x00; - } - - public boolean getfParity() { - return (this.intValue() & (0x01 << 1)) != 0x00; - } - - public int getfRtsControl() { - return (this.intValue() >>> 12) & 0x03; - } - - public int getfDummy2() { - return (this.intValue()>>>15) & 0x1FFFF; - } - - public boolean getfTXContinueOnXoff() { - return (this.intValue() & (0x01 << 7)) != 0x00; - } - - /** - * If this member is TRUE, the driver terminates all read and write - * operations with an error status if an error occurs.
    - * The driver will not accept any further communications operations - * until the application has acknowledged the error by calling the - * ClearCommError function. - * - * @param fAbortOnError - */ - public void setfAbortOnError(boolean fAbortOnError) { - int tmp = leftShiftMask(fAbortOnError ? 1 : 0, (byte)14, 0x01, this.intValue()); - this.setValue(tmp); - } - - /** - * If this member is TRUE, binary mode is enabled.
    - * Windows does not support nonbinary mode transfers, so this member - * must be TRUE. - * - * @param fBinary - */ - public void setfBinary(boolean fBinary) { - int tmp = leftShiftMask(fBinary ? 1 : 0, (byte)0, 0x01, this.intValue()); - this.setValue(tmp); - } - - /** - * If this member is TRUE, the communications driver is sensitive to the - * state of the DSR signal.
    - * The driver ignores any bytes received, unless the DSR modem input - * line is high. - * - * @param fDsrSensitivity - */ - public void setfDsrSensitivity(boolean fDsrSensitivity) { - int tmp = leftShiftMask(fDsrSensitivity ? 1 : 0, (byte)6, 0x01, this.intValue()); - this.setValue(tmp); - } - - /** - * The DTR (data-terminal-ready) flow control. This member can be one of - * the following values. - *
  • {@link WinBase#DTR_CONTROL_DISABLE}
  • - *
  • {@link WinBase#DTR_CONTROL_ENABLE}
  • - *
  • {@link WinBase#DTR_CONTROL_HANDSHAKE}
  • - * - * @param fOutxDsrFlow - * value to set - */ - public void setfDtrControl(int fOutxDsrFlow) { - int tmp = leftShiftMask(fOutxDsrFlow, (byte)4, 0x03, this.intValue()); - this.setValue(tmp); - } - - /** - * Indicates whether bytes received with parity errors are replaced with - * the character specified by the ErrorChar member.
    - * If this member is TRUE and the fParity member is TRUE, replacement - * occurs. - * - * @param fErrorChar - */ - public void setfErrorChar(boolean fErrorChar) { - int tmp = leftShiftMask(fErrorChar ? 1 : 0, (byte)10, 0x01, this.intValue()); - this.setValue(tmp); - } - - /** - * Indicates whether XON/XOFF flow control is used during reception.
    - * If this member is TRUE, the XoffChar character is sent when the input - * buffer comes within XoffLim bytes of being full, and the XonChar - * character is sent when the input buffer comes within XonLim bytes of - * being empty. - * - * @param fInX - */ - public void setfInX(boolean fInX) { - int tmp = leftShiftMask(fInX ? 1 : 0, (byte)9, 0x01, this.intValue()); - this.setValue(tmp); - } - - /** - * If this member is TRUE, null bytes are discarded when received. - * - * @param fNull - */ - public void setfNull(boolean fNull) { - int tmp = leftShiftMask(fNull ? 1 : 0, (byte)11, 0x01, this.intValue()); - this.setValue(tmp); - } - - /** - * Indicates whether XON/XOFF flow control is used during transmission. - *
    - * If this member is TRUE, transmission stops when the XoffChar - * character is received and starts again when the XonChar character is - * received. - * - * @param fOutX - */ - public void setfOutX(boolean fOutX) { - int tmp = leftShiftMask(fOutX ? 1 : 0, (byte)8, 0x01, this.intValue()); - this.setValue(tmp); - } - - /** - * If this member is TRUE, the CTS (clear-to-send) signal is monitored - * for output flow control.
    - * If this member is TRUE and CTS is turned off, output is suspended - * until CTS is sent again. - * - * @param fOutxCtsFlow - */ - public void setfOutxCtsFlow(boolean fOutxCtsFlow) { - int tmp = leftShiftMask(fOutxCtsFlow ? 1 : 0, (byte)2, 0x01, this.intValue()); - this.setValue(tmp); - } - - /** - * If this member is TRUE, the DSR (data-set-ready) signal is monitored - * for output flow control.
    - * If this member is TRUE and DSR is turned off, output is suspended - * until DSR is sent again. - * - * @param fOutxDsrFlow - */ - public void setfOutxDsrFlow(boolean fOutxDsrFlow) { - int tmp = leftShiftMask(fOutxDsrFlow ? 1 : 0, (byte)3, 0x01, this.intValue()); - this.setValue(tmp); - } - - /** - * If this member is TRUE, parity checking is performed and errors are - * reported. - * - * @param fParity - */ - public void setfParity(boolean fParity) { - int tmp = leftShiftMask(fParity ? 1 : 0, (byte)1, 0x01, this.intValue()); - this.setValue(tmp); - } - - /** - * - * The RTS (request-to-send) flow control. This member can be one of the - * following values. - *
  • {@link WinBase#RTS_CONTROL_DISABLE}
  • - *
  • {@link WinBase#RTS_CONTROL_ENABLE}
  • - *
  • {@link WinBase#RTS_CONTROL_HANDSHAKE}
  • - *
  • {@link WinBase#RTS_CONTROL_TOGGLE}
  • - * - * @param fRtsControl - */ - public void setfRtsControl(int fRtsControl) { - int tmp = leftShiftMask(fRtsControl, (byte)12, 0x03, this.intValue()); - this.setValue(tmp); - } - - /** - * If this member is TRUE, transmission continues after the input buffer - * has come within XoffLim bytes of being full and the driver has - * transmitted the XoffChar character to stop receiving bytes.
    - * If this member is FALSE, transmission does not continue until the - * input buffer is within XonLim bytes of being empty and the driver has - * transmitted the XonChar character to resume reception. - * - * @param fTXContinueOnXoff - */ - public void setfTXContinueOnXoff(boolean fTXContinueOnXoff) { - int tmp = leftShiftMask(fTXContinueOnXoff ? 1 : 0, (byte)7, 0x01, this.intValue()); - this.setValue(tmp); - } - - - private static int leftShiftMask(int valuetoset, byte shift, int mask, int storage) { - int tmp = storage; - tmp &= ~(mask << shift); - tmp |= ((valuetoset & mask) << shift); - return tmp; - } - } - /** - * The length of the structure, in bytes. The caller must set this - * member to sizeof(DCB). - */ - public DWORD DCBlength; - - /** - * - * The baud rate at which the communications device operates. This - * member can be an actual baud rate value, or one of the following - * indexes. - *
  • {@link WinBase#CBR_110}
  • - *
  • {@link WinBase#CBR_300}
  • - *
  • {@link WinBase#CBR_600}
  • - *
  • {@link WinBase#CBR_1200}
  • - *
  • {@link WinBase#CBR_2400}
  • - *
  • {@link WinBase#CBR_4800}
  • - *
  • {@link WinBase#CBR_9600}
  • - *
  • {@link WinBase#CBR_14400}
  • - *
  • {@link WinBase#CBR_19200}
  • - *
  • {@link WinBase#CBR_38400}
  • - *
  • {@link WinBase#CBR_56000}
  • - *
  • {@link WinBase#CBR_128000}
  • - *
  • {@link WinBase#CBR_256000}
  • - * - */ - public DWORD BaudRate; - - /** - * Contains all the bit wise setting entries. - */ - public DCBControllBits controllBits; - - /** - * Reserved; must be zero. - */ - public WORD wReserved; - - /** - * The minimum number of bytes in use allowed in the input buffer before - * flow control is activated to allow transmission by the sender. This - * assumes that either XON/XOFF, RTS, or DTR input flow control is - * specified in the fInX, fRtsControl, or fDtrControl members. - */ - public WORD XonLim; - - /** - * The minimum number of free bytes allowed in the input buffer before - * flow control is activated to inhibit the sender. Note that the sender - * may transmit characters after the flow control signal has been - * activated, so this value should never be zero. This assumes that - * either XON/XOFF, RTS, or DTR input flow control is specified in the - * fInX, fRtsControl, or fDtrControl members. The maximum number of - * bytes in use allowed is calculated by subtracting this value from the - * size, in bytes, of the input buffer. - */ - public WORD XoffLim; - - /** - * The number of bits in the bytes transmitted and received. - */ - public BYTE ByteSize; - - /** - * - * The parity scheme to be used. This member can be one of the following - * values. - *
  • {@link WinBase#EVENPARITY}
  • - *
  • {@link WinBase#ODDPARITY}
  • - *
  • {@link WinBase#NOPARITY}
  • - *
  • {@link WinBase#SPACEPARITY}
  • - *
  • {@link WinBase#MARKPARITY}
  • - */ - public BYTE Parity; - - /** - * The number of stop bits to be used. This member can be one of the - * following values. - *
  • {@link WinBase#ONESTOPBIT}
  • - *
  • {@link WinBase#ONE5STOPBITS}
  • - *
  • {@link WinBase#TWOSTOPBITS}
  • - */ - public BYTE StopBits; - - /** - * The value of the XON character for both transmission and reception. - */ - public char XonChar; - - /** - * The value of the XOFF character for both transmission and reception. - */ - public char XoffChar; - - /** - * The value of the character used to replace bytes received with a - * parity error. - */ - public char ErrorChar; - - /** - * The value of the character used to signal the end of data. - */ - public char EofChar; - - /** - * The value of the character used to signal an event. - */ - public char EvtChar; - - /** - * Reserved; do not use. - */ - public WORD wReserved1; - - public DCB() { - DCBlength = new DWORD(size()); - } - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "DCBlength", "BaudRate", "controllBits", "wReserved", "XonLim", - "XoffLim", "ByteSize", "Parity", "StopBits", "XonChar", "XoffChar", "ErrorChar", "EofChar", - "EvtChar", "wReserved1" }); - } - } - - /** - * No parity. - */ - int NOPARITY = 0; - - /** - * Odd parity. - */ - int ODDPARITY = 1; - - /** - * Even parity. - */ - int EVENPARITY = 2; - - /** - * Mark parity. - */ - int MARKPARITY = 3; - - /** - * Space parity. - */ - int SPACEPARITY = 4; - - /** - * 1 stop bit. - */ - int ONESTOPBIT = 0; - - /** - * 1.5 stop bits. - */ - int ONE5STOPBITS = 1; - /** - * 2 stop bits. - */ - int TWOSTOPBITS = 2; - /** - * 110 bps. - */ - int CBR_110 = 110; - /** - * 300 bps. - */ - int CBR_300 = 300; - /** - * 600 bps. - */ - int CBR_600 = 600; - /** - * 1200 bps. - */ - int CBR_1200 = 1200; - /** - * 2400 bps. - */ - int CBR_2400 = 2400; - /** - * 4800 bps. - */ - int CBR_4800 = 4800; - /** - * 9600 bps. - */ - int CBR_9600 = 9600; - /** - * 14400 bps. - */ - int CBR_14400 = 14400; - /** - * 19200 bps. - */ - int CBR_19200 = 19200; - /** - * 38400 bps. - */ - int CBR_38400 = 38400; - /** - * 56000 bps. - */ - int CBR_56000 = 56000; - - /** - * 128000 bps. - */ - int CBR_128000 = 128000; - - /** - * 256000 bps. - */ - int CBR_256000 = 256000; - - /** - * Disables the DTR line when the device is opened and leaves it disabled. - */ - int DTR_CONTROL_DISABLE = 0; - - /** - * Enables the DTR line when the device is opened and leaves it on. - */ - int DTR_CONTROL_ENABLE = 1; - - /** - * Enables DTR handshaking.
    - * If handshaking is enabled, it is an error for the application to adjust - * the line by using the EscapeCommFunction function. - */ - int DTR_CONTROL_HANDSHAKE = 2; - - /** - * Disables the RTS line when the device is opened and leaves it disabled. - */ - int RTS_CONTROL_DISABLE = 0; - - /** - * Enables the RTS line when the device is opened and leaves it on. - */ - int RTS_CONTROL_ENABLE = 1; - - /** - * Enables RTS handshaking.
    - * The driver raises the RTS line when the "type-ahead" (input) buffer is - * less than one-half full and lowers the RTS line when the buffer is more - * than three-quarters full.
    - * If handshaking is enabled, it is an error for the application to adjust - * the line by using the EscapeCommFunction function. - */ - int RTS_CONTROL_HANDSHAKE = 2; - - /** - * Specifies that the RTS line will be high if bytes are available for - * transmission.
    - * After all buffered bytes have been sent, the RTS line will be low. - */ - int RTS_CONTROL_TOGGLE = 3;; + /** + * An application-defined callback function used with the EnumResourceTypes + * and EnumResourceTypesEx functions.
    + * It receives resource types.
    + * The ENUMRESTYPEPROC type defines a pointer to this callback function. + *
    + * EnumResTypeProc is a placeholder for the application-defined function + * name. + */ + interface EnumResTypeProc extends Callback { + /** + * @param module + * A handle to the module whose executable file contains the + * resources for which the types are to be enumerated.
    + * If this parameter is NULL, the function enumerates the + * resource types in the module used to create the current + * process. + * @param type + * The type of resource for which the type is being + * enumerated.
    + * Alternately, rather than a pointer, this parameter can be + * MAKEINTRESOURCE(ID), where ID is the integer identifier of + * the given resource type.
    + * For standard resource types, see Resource Types.
    + * For more information, see the Remarks section below. + * @param lParam + * An application-defined parameter passed to the + * EnumResourceTypes or EnumResourceTypesEx function.
    + * This parameter can be used in error checking. + * @return Returns TRUE to continue enumeration or FALSE to stop + * enumeration. + */ + boolean invoke(HMODULE module, Pointer type, Pointer lParam); + } + /** + * An application-defined callback function used with the EnumResourceNames + * and EnumResourceNamesEx functions.
    + * It receives the type and name of a resource.
    + * The ENUMRESNAMEPROC type defines a pointer to this callback function. + *
    + * EnumResNameProc is a placeholder for the application-defined function + * name. + */ + interface EnumResNameProc extends Callback { + /** + * @param module + * A handle to the module whose executable file contains the + * resources that are being enumerated.
    + * If this parameter is NULL, the function enumerates the + * resource names in the module used to create the current + * process. + * @param type + * The type of resource for which the name is being + * enumerated.
    + * Alternately, rather than a pointer, this parameter can be + * MAKEINTRESOURCE(ID), where ID is an integer + * value representing a predefined resource type.
    + * For standard resource types, see + * Resource Types.
    + * For more information, see the Remarks section below. + * @param name + * The name of a resource of the type being enumerated.
    + * Alternately, rather than a pointer, this parameter can be + * MAKEINTRESOURCE(ID), where ID is the integer + * identifier of the resource.
    + * For more information, see the Remarks section below. + * @param lParam + * An application-defined parameter passed to the + * EnumResourceNames or EnumResourceNamesEx function.
    + * This parameter can be used in error checking. + * @return Returns TRUE to continue enumeration or FALSE to stop + * enumeration. + */ + boolean invoke(HMODULE module, Pointer type, Pointer name, Pointer lParam); + } + + /** + * Enables away mode. This value must be specified with {@link #ES_CONTINUOUS}. + * + * Away mode should be used only by media-recording and media-distribution + * applications that must perform critical background processing on desktop + * computers while the computer appears to be sleeping. See Remarks. + */ + int ES_AWAYMODE_REQUIRED = 0x00000040; + /** + * Informs the system that the state being set should remain in effect until + * the next call that uses ES_CONTINUOUS and one of the other state flags is + * cleared. + */ + int ES_CONTINUOUS = 0x80000000; + /** + * Forces the display to be on by resetting the display idle timer. + */ + int ES_DISPLAY_REQUIRED = 0x00000002; + /** + * Forces the system to be in the working state by resetting the system idle + * timer. + */ + int ES_SYSTEM_REQUIRED = 0x00000001; + /** + * This value is not supported. If ES_USER_PRESENT is combined with other + * esFlags values, the call will fail and none of the specified states will + * be set. + */ + int ES_USER_PRESENT = 0x00000004; } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Wincon.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Wincon.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Wincon.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Wincon.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/WinCrypt.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/WinCrypt.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/WinCrypt.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/WinCrypt.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,18 +1,28 @@ /* 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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 java.util.Arrays; import java.util.List; import com.sun.jna.Memory; @@ -20,23 +30,33 @@ import com.sun.jna.Pointer; import com.sun.jna.Structure; import com.sun.jna.platform.win32.WinDef.HWND; -import com.sun.jna.win32.StdCallLibrary; +import com.sun.jna.win32.W32APITypeMapper; /** * Ported from WinCrypt.h. * Microsoft Windows SDK 6.0A. * @author dblock[at]dblock.org */ -public interface WinCrypt extends StdCallLibrary { - +public interface WinCrypt { + /** * The CryptoAPI CRYPTOAPI_BLOB structure is used for an arbitrary array of bytes. */ public static class DATA_BLOB extends Structure { + public static final List FIELDS = createFieldsOrder("cbData", "pbData"); + /** + * The count of bytes in the buffer pointed to by pbData. + */ + public int cbData; + /** + * A pointer to a block of data bytes. + */ + public Pointer pbData; + public DATA_BLOB() { super(); } - + public DATA_BLOB(Pointer memory) { super(memory); read(); @@ -48,22 +68,15 @@ cbData = data.length; allocateMemory(); } - + public DATA_BLOB(String s) { this(Native.toByteArray(s)); } - - /** - * The count of bytes in the buffer pointed to by pbData. - */ - public int cbData; - /** - * A pointer to a block of data bytes. - */ - public Pointer pbData; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "cbData", "pbData" }); + + + @Override + protected List getFieldOrder() { + return FIELDS; } /** * Get byte data. @@ -73,23 +86,15 @@ public byte[] getData() { return pbData == null ? null : pbData.getByteArray(0, cbData); } - } - + } + /** - * The CRYPTPROTECT_PROMPTSTRUCT structure provides the text of a prompt and + * The CRYPTPROTECT_PROMPTSTRUCT structure provides the text of a prompt and * information about when and where that prompt is to be displayed when using - * the CryptProtectData and CryptUnprotectData functions. + * the CryptProtectData and CryptUnprotectData functions. */ public static class CRYPTPROTECT_PROMPTSTRUCT extends Structure { - public CRYPTPROTECT_PROMPTSTRUCT() { - super(); - } - - public CRYPTPROTECT_PROMPTSTRUCT(Pointer memory) { - super(memory); - read(); - } - + public static final List FIELDS = createFieldsOrder("cbSize", "dwPromptFlags", "hwndApp", "szPrompt"); /** * Size of this structure in bytes. */ @@ -99,19 +104,29 @@ */ public int dwPromptFlags; /** - * Window handle to the parent window. + * Window handle to the parent window. */ public HWND hwndApp; /** - * A string containing the text of a prompt to be displayed. + * A string containing the text of a prompt to be displayed. */ public String szPrompt; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "cbSize", "dwPromptFlags", "hwndApp", "szPrompt" }); + + public CRYPTPROTECT_PROMPTSTRUCT() { + super(W32APITypeMapper.DEFAULT); + } + + public CRYPTPROTECT_PROMPTSTRUCT(Pointer memory) { + super(memory, Structure.ALIGN_DEFAULT, W32APITypeMapper.DEFAULT); + read(); + } + + @Override + protected List getFieldOrder() { + return FIELDS; } } - + // // CryptProtect PromptStruct dwPromtFlags // @@ -127,7 +142,7 @@ /** * Reserved, don't use. */ - int CRYPTPROTECT_PROMPT_RESERVED = 0x04; + int CRYPTPROTECT_PROMPT_RESERVED = 0x04; /** * Default to strong variant UI protection (user supplied password currently). */ @@ -141,18 +156,18 @@ // CryptProtectData and CryptUnprotectData dwFlags // /** - * For remote-access situations where ui is not an option, if UI was specified - * on protect or unprotect operation, the call will fail and GetLastError() will + * For remote-access situations where ui is not an option, if UI was specified + * on protect or unprotect operation, the call will fail and GetLastError() will * indicate ERROR_PASSWORD_RESTRICTION. */ int CRYPTPROTECT_UI_FORBIDDEN = 0x1; /** - * Per machine protected data -- any user on machine where CryptProtectData + * Per machine protected data -- any user on machine where CryptProtectData * took place may CryptUnprotectData. */ int CRYPTPROTECT_LOCAL_MACHINE = 0x4; /** - * Force credential synchronize during CryptProtectData() + * Force credential synchronize during CryptProtectData() * Synchronize is only operation that occurs during this operation. */ int CRYPTPROTECT_CRED_SYNC = 0x8; @@ -172,4 +187,118 @@ * Regenerate the local machine protection. */ int CRYPTPROTECT_CRED_REGENERATE = 0x80; + + /** + * ASN.1 Certificate encode/decode return value base + * @see MSDN + */ + int CRYPT_E_ASN1_ERROR = 0x80093100; + + /** + * ASN.1 internal encode or decode error + * @see MSDN + */ + int CRYPT_E_ASN1_INTERNAL = 0x80093101; + + /** + * ASN.1 unexpected end of data + * @see MSDN + */ + int CRYPT_E_ASN1_EOD = 0x80093102; + + /** + * ASN.1 corrupted data + * @see MSDN + */ + int CRYPT_E_ASN1_CORRUPT = 0x80093103; + + /** + * ASN.1 value too large + * @see MSDN + */ + int CRYPT_E_ASN1_LARGE = 0x80093104; + + /** + * ASN.1 constraint violated + * @see MSDN + */ + int CRYPT_E_ASN1_CONSTRAINT = 0x80093105; + + /** + * ASN.1 out of memory + * @see MSDN + */ + int CRYPT_E_ASN1_MEMORY = 0x80093106; + + /** + * ASN.1 buffer overflow + * @see MSDN + */ + int CRYPT_E_ASN1_OVERFLOW = 0x80093107; + + /** + * ASN.1 function not supported for this PDU + * @see MSDN + */ + int CRYPT_E_ASN1_BADPDU = 0x80093108; + + /** + * ASN.1 bad arguments to function call + * @see MSDN + */ + int CRYPT_E_ASN1_BADARGS = 0x80093109; + + /** + * ASN.1 bad real value + * @see MSDN + */ + int CRYPT_E_ASN1_BADREAL = 0x8009310A; + + /** + * ASN.1 bad tag value met + * @see MSDN + */ + int CRYPT_E_ASN1_BADTAG = 0x8009310B; + + /** + * ASN.1 bad choice value + * @see MSDN + */ + int CRYPT_E_ASN1_CHOICE = 0x8009310C; + + /** + * ASN.1 bad encoding rule + * @see MSDN + */ + int CRYPT_E_ASN1_RULE = 0x8009310D; + + /** + * ASN.1 bad Unicode (UTF8) + * @see MSDN + */ + int CRYPT_E_ASN1_UTF8 = 0x8009310E; + + /** + * ASN.1 bad PDU type + * @see MSDN + */ + int CRYPT_E_ASN1_PDU_TYPE = 0x80093133; + + /** + * ASN.1 not yet implemented + * @see MSDN + */ + int CRYPT_E_ASN1_NYI = 0x80093134; + + /** + * ASN.1 skipped unknown extensions + * @see MSDN + */ + int CRYPT_E_ASN1_EXTENDED = 0x80093201; + + /** + * ASN.1 end of data expected + * @see MSDN + */ + int CRYPT_E_ASN1_NOEOD = 0x80093202; } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/WinDef.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/WinDef.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/WinDef.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/WinDef.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,19 +1,29 @@ /* Copyright (c) 2010 Daniel Doubrovkine, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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 java.awt.Rectangle; -import java.util.Arrays; import java.util.List; import com.sun.jna.IntegerType; @@ -25,7 +35,6 @@ import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.platform.win32.WinNT.HANDLEByReference; import com.sun.jna.ptr.ByReference; -import com.sun.jna.win32.StdCallLibrary; /** * Ported from Windef.h (various macros and types). Microsoft Windows SDK 6.0A. @@ -33,7 +42,7 @@ * @author dblock[at]dblock.org */ @SuppressWarnings("serial") -public interface WinDef extends StdCallLibrary { +public interface WinDef { /** The max path. */ int MAX_PATH = 260; @@ -141,7 +150,7 @@ * @return Low WORD. */ public WORD getLow() { - return new WORD(longValue() & 0xFF); + return new WORD(longValue() & 0xFFFF); } /** @@ -150,7 +159,7 @@ * @return High WORD. */ public WORD getHigh() { - return new WORD((longValue() >> 16) & 0xFF); + return new WORD((longValue() >> 16) & 0xFFFF); } @Override @@ -239,7 +248,7 @@ * Instantiates a new LONG by reference. */ public LONGByReference() { - this(new LONG(0)); + this(new LONG(0L)); } /** @@ -756,7 +765,7 @@ * The Class RECT. */ public class RECT extends Structure { - + public static final List FIELDS = createFieldsOrder("left", "top", "right", "bottom"); /** The left. */ public int left; @@ -771,7 +780,7 @@ @Override protected List getFieldOrder() { - return Arrays.asList("left", "top", "right", "bottom"); + return FIELDS; } /** @@ -1057,14 +1066,21 @@ /** * The Class ByReference. */ - public static class ByReference extends POINT implements - Structure.ByReference { + public static class ByReference extends POINT implements Structure.ByReference { + } + public static final List FIELDS = createFieldsOrder("x", "y"); + + /** The x. */ + public int x; + /** The y. */ + public int y; /** * Instantiates a new point. */ public POINT() { + super(); } /** @@ -1078,9 +1094,6 @@ read(); } - /** The y. */ - public int x, y; - /** * Instantiates a new point. * @@ -1096,7 +1109,7 @@ @Override protected List getFieldOrder() { - return Arrays.asList("x", "y"); + return FIELDS; } } @@ -1402,6 +1415,7 @@ */ public BOOL(long value) { super(SIZE, value, false); + assert value == 0 || value == 1; } public boolean booleanValue() { @@ -1595,7 +1609,7 @@ * * @param ch The {@code char} value */ - public CHAR(char ch) { + public CHAR(byte ch) { this(ch & 0xFF); } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/WinError.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/WinError.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/WinError.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/WinError.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2011 Daniel Doubrovkine, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Winevt.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Winevt.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Winevt.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Winevt.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,1709 @@ +/* Copyright (c) 2016 Minoru Sakamoto, 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.*; +import com.sun.jna.platform.win32.WinDef.BOOL; +import com.sun.jna.platform.win32.WinNT.HANDLE; +import com.sun.jna.win32.W32APITypeMapper; + +import java.util.Arrays; +import java.util.List; + +/** + * Ported from winevt.h. + * Microsoft Windows SDK 10.0.10586 + * + * @author Minoru Sakamoto + */ +public interface Winevt { + + /** + * Defines the possible data types of a variant data item. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385616(v=vs.85).aspx + */ + public static enum EVT_VARIANT_TYPE { + + /** Null content that implies that the element that contains the content does not exist. */ + EvtVarTypeNull(""), + + /** A null-terminated Unicode string. */ + EvtVarTypeString("String"), + + /** A null-terminated ANSI string. */ + EvtVarTypeAnsiString("AnsiString"), + + /** A signed 8-bit integer value. */ + EvtVarTypeSByte("SByte"), + + /** An unsigned 8-bit integer value. */ + EvtVarTypeByte("Byte"), + + /** An signed 16-bit integer value. */ + EvtVarTypeInt16("Int16"), + + /** An unsigned 16-bit integer value. */ + EvtVarTypeUInt16("UInt16"), + + /** A signed 32-bit integer value. */ + EvtVarTypeInt32("Int32"), + + /** An unsigned 32-bit integer value. */ + EvtVarTypeUInt32("UInt32"), + + /** A signed 64-bit integer value. */ + EvtVarTypeInt64("Int64"), + + /** An unsigned 64-bit integer value. */ + EvtVarTypeUInt64("UInt64"), + + /** A single-precision real value. */ + EvtVarTypeSingle("Single"), + + /** A double-precision real value. */ + EvtVarTypeDouble("Double"), + + /** A Boolean value. */ + EvtVarTypeBoolean("Boolean"), + + /** A hexadecimal binary value. */ + EvtVarTypeBinary("Binary"), + + /** A GUID value. */ + EvtVarTypeGuid("Guid"), + + /** An unsigned 32-bit or 64-bit integer value that contains a pointer address. */ + EvtVarTypeSizeT("SizeT"), + + /** A FILETIME value. */ + EvtVarTypeFileTime("FileTime"), + + /** A SYSTEMTIME value. */ + EvtVarTypeSysTime("SysTime"), + + /** A security identifier (SID) structure */ + EvtVarTypeSid("Sid"), + + /** A 32-bit hexadecimal number. */ + EvtVarTypeHexInt32("Int32"), + + /** A 64-bit hexadecimal number. */ + EvtVarTypeHexInt64("Int64"), + + /** An EVT_HANDLE value. */ + EvtVarTypeEvtHandle("EvtHandle"), + + /** A null-terminated Unicode string that contains XML. */ + EvtVarTypeEvtXml("Xml"); + + private final String field; + + private EVT_VARIANT_TYPE(String field) { + this.field = field; + } + + public String getField() { + return this.field.isEmpty() ? "" : this.field + "Val"; + } + + public String getArrField() { + return this.field.isEmpty() ? "" : this.field + "Arr"; + } + } + + /** + * The Type member of the EVT_VARIANT structure has this bit set if the variant contains a pointer to an array of + * values, rather than the value itself. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385781(v=vs.85).aspx + */ + public static final int EVT_VARIANT_TYPE_ARRAY = 128; + + /** + * A bitmask that you use to mask out the array bit of the variant type, so you can determine the data type of + * the variant value that the EVT_VARIANT structure contains. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385781(v=vs.85).aspx + */ + public static final int EVT_VARIANT_TYPE_MASK = 0x7f; + + /** + * Defines the types of connection methods you can use to connect to the remote computer. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385529(v=vs.85).aspx + */ + public static interface EVT_LOGIN_CLASS { + + /** Use Remote Procedure Call (RPC) login. */ + public static final int EvtRpcLogin = 1; + } + + /** + * Contains event data or property values. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385611(v=vs.85).aspx + */ + public static class EVT_VARIANT extends Structure { + /** + * Exposed to follow JNA rules, use the + * {@link EVT_VARIANT#getValue} method + * to manipulate values! + */ + public field1_union field1; + + /* + Defined to get correct size for the union. Data is accessed by direct + read from memory. + */ + public static class field1_union extends Union { + + public byte byteValue; + + public short shortValue; + + public int intValue; + + public long longValue; + + public float floatValue; + + public double doubleVal; + + public Pointer pointerValue; + } + + /** + * The number of elements in the array of values. Use Count if the Type member has + * the EVT_VARIANT_TYPE_ARRAY flag set. + *

    + * Exposed to follow JNA rules, use + * {@link EVT_VARIANT#getValue} and {@link EVT_VARIANT#setValue} methods + * to manipulate values! + */ + public int Count; + + /** + * A flag that specifies the data type of the variant. For possible values, see + * the {@link Winevt.EVT_VARIANT_TYPE} enumeration. + * The variant contains an array of values, if the EVT_VARIANT_TYPE_ARRAY flag is set. The members that end in + * "Arr" contain arrays of values. For example, you would use the StringArr member to access the variant data + * if the type is EvtVarTypeString and the EVT_VARIANT_TYPE_ARRAY flag is set. + * You can use the {@link Winevt#EVT_VARIANT_TYPE_MASK} constant to mask out the array bit to determine + * the variant's type. + *

    + * Exposed to follow JNA rules, use + * {@link EVT_VARIANT#getValue} and {@link EVT_VARIANT#setValue} methods + * to manipulate values! + */ + public int Type; + + public EVT_VARIANT() { + super(W32APITypeMapper.DEFAULT); + } + + protected List getFieldOrder() { + return Arrays.asList("field1", "Count", "Type"); + } + + public EVT_VARIANT(Pointer peer) { + super(peer, Structure.ALIGN_DEFAULT, W32APITypeMapper.DEFAULT); + } + + public void use(Pointer m) { + useMemory(m, 0); + } + + public static class ByReference extends EVT_VARIANT implements Structure.ByReference { + public ByReference(Pointer p) { + super(p); + } + + public ByReference() { + super(); + } + } + + public static class ByValue extends EVT_VARIANT implements Structure.ByValue { + public ByValue(Pointer p) { + super(p); + } + + public ByValue() { + + } + } + + + private int getBaseType() { + return Type & EVT_VARIANT_TYPE_MASK; + } + + public boolean isArray() { + return (Type & EVT_VARIANT_TYPE_ARRAY) == EVT_VARIANT_TYPE_ARRAY; + } + + public EVT_VARIANT_TYPE getVariantType() { + return EVT_VARIANT_TYPE.values()[getBaseType()]; + } + + // Helper to store java object for set values + private Object holder; + + /** + * @param type + * @param value + */ + public void setValue(EVT_VARIANT_TYPE type, Object value) { + allocateMemory(); + if (type == null) { + throw new IllegalArgumentException("setValue must not be called with type set to NULL"); + } + holder = null; + if (value == null || type == EVT_VARIANT_TYPE.EvtVarTypeNull) { + Type = EVT_VARIANT_TYPE.EvtVarTypeNull.ordinal(); + Count = 0; + field1.writeField("pointerValue", Pointer.NULL); + } else { + switch (type) { + case EvtVarTypeAnsiString: + if (value.getClass().isArray() && value.getClass().getComponentType() == String.class) { + Type = type.ordinal() | EVT_VARIANT_TYPE_ARRAY; + StringArray sa = new StringArray((String[]) value, false); + holder = sa; + Count = ((String[]) value).length; + field1.writeField("pointerValue", sa); + } else if (value.getClass() == String.class) { + Type = type.ordinal(); + Memory mem = new Memory(((String) value).length() + 1); + mem.setString(0, (String) value); + holder = mem; + Count = 0; + field1.writeField("pointerValue", mem); + } else { + throw new IllegalArgumentException(type.name() + " must be set from String/String[]"); + } + break; + case EvtVarTypeBoolean: + if (value.getClass().isArray() && value.getClass().getComponentType() == BOOL.class) { + Type = type.ordinal() | EVT_VARIANT_TYPE_ARRAY; + Memory mem = new Memory(((BOOL[]) value).length * 4); + for (int i = 0; i < ((BOOL[]) value).length; i++) { + mem.setInt(i * 4, ((BOOL[]) value)[i].intValue()); + } + holder = mem; + Count = 0; + field1.writeField("pointerValue", mem); + } else if (value.getClass() == BOOL.class) { + Type = type.ordinal(); + Count = 0; + field1.writeField("intValue", ((BOOL) value).intValue()); + } else { + throw new IllegalArgumentException(type.name() + " must be set from BOOL/BOOL[]"); + } + break; + case EvtVarTypeString: + case EvtVarTypeEvtXml: + if (value.getClass().isArray() && value.getClass().getComponentType() == String.class) { + Type = type.ordinal() | EVT_VARIANT_TYPE_ARRAY; + StringArray sa = new StringArray((String[]) value, true); + holder = sa; + Count = ((String[]) value).length; + field1.writeField("pointerValue", sa); + } else if (value.getClass() == String.class) { + Type = type.ordinal(); + Memory mem = new Memory((((String) value).length() + 1) * 2); + mem.setWideString(0, (String) value); + holder = mem; + Count = 0; + field1.writeField("pointerValue", mem); + } else { + throw new IllegalArgumentException(type.name() + " must be set from String/String[]"); + } + break; + case EvtVarTypeSByte: + case EvtVarTypeByte: + if (value.getClass().isArray() && value.getClass().getComponentType() == byte.class) { + Type = type.ordinal() | EVT_VARIANT_TYPE_ARRAY; + Memory mem = new Memory(((byte[]) value).length * 1); + mem.write(0, (byte[]) value, 0, ((byte[]) value).length); + holder = mem; + Count = 0; + field1.writeField("pointerValue", mem); + } else if (value.getClass() == byte.class) { + Type = type.ordinal(); + Count = 0; + field1.writeField("byteValue", value); + } else { + throw new IllegalArgumentException(type.name() + " must be set from byte/byte[]"); + } + break; + case EvtVarTypeInt16: + case EvtVarTypeUInt16: + if (value.getClass().isArray() && value.getClass().getComponentType() == short.class) { + Type = type.ordinal() | EVT_VARIANT_TYPE_ARRAY; + Memory mem = new Memory(((short[]) value).length * 2); + mem.write(0, (short[]) value, 0, ((short[]) value).length); + holder = mem; + Count = 0; + field1.writeField("pointerValue", mem); + } else if (value.getClass() == short.class) { + Type = type.ordinal(); + Count = 0; + field1.writeField("shortValue", value); + } else { + throw new IllegalArgumentException(type.name() + " must be set from short/short[]"); + } + break; + case EvtVarTypeHexInt32: + case EvtVarTypeInt32: + case EvtVarTypeUInt32: + if (value.getClass().isArray() && value.getClass().getComponentType() == int.class) { + Type = type.ordinal() | EVT_VARIANT_TYPE_ARRAY; + Memory mem = new Memory(((int[]) value).length * 4); + mem.write(0, (int[]) value, 0, ((int[]) value).length); + holder = mem; + Count = 0; + field1.writeField("pointerValue", mem); + } else if (value.getClass() == int.class) { + Type = type.ordinal(); + Count = 0; + field1.writeField("intValue", value); + } else { + throw new IllegalArgumentException(type.name() + " must be set from int/int[]"); + } + break; + case EvtVarTypeHexInt64: + case EvtVarTypeInt64: + case EvtVarTypeUInt64: + if (value.getClass().isArray() && value.getClass().getComponentType() == long.class) { + Type = type.ordinal() | EVT_VARIANT_TYPE_ARRAY; + Memory mem = new Memory(((long[]) value).length * 4); + mem.write(0, (long[]) value, 0, ((long[]) value).length); + holder = mem; + Count = 0; + field1.writeField("pointerValue", mem); + } else if (value.getClass() == long.class) { + Type = type.ordinal(); + Count = 0; + field1.writeField("longValue", value); + } else { + throw new IllegalArgumentException(type.name() + " must be set from long/long[]"); + } + break; + case EvtVarTypeSingle: + if (value.getClass().isArray() && value.getClass().getComponentType() == float.class) { + Type = type.ordinal() | EVT_VARIANT_TYPE_ARRAY; + Memory mem = new Memory(((float[]) value).length * 4); + mem.write(0, (float[]) value, 0, ((float[]) value).length); + holder = mem; + Count = 0; + field1.writeField("pointerValue", mem); + } else if (value.getClass() == float.class) { + Type = type.ordinal(); + Count = 0; + field1.writeField("floatValue", value); + } else { + throw new IllegalArgumentException(type.name() + " must be set from float/float[]"); + } + break; + case EvtVarTypeDouble: + if (value.getClass().isArray() && value.getClass().getComponentType() == double.class) { + Type = type.ordinal() | EVT_VARIANT_TYPE_ARRAY; + Memory mem = new Memory(((double[]) value).length * 4); + mem.write(0, (double[]) value, 0, ((double[]) value).length); + holder = mem; + Count = 0; + field1.writeField("pointerValue", mem); + } else if (value.getClass() == double.class) { + Type = type.ordinal(); + Count = 0; + field1.writeField("doubleVal", value); + } else { + throw new IllegalArgumentException(type.name() + " must be set from double/double[]"); + } + break; + case EvtVarTypeBinary: + if (value.getClass().isArray() && value.getClass().getComponentType() == byte.class) { + Type = type.ordinal(); + Memory mem = new Memory(((byte[]) value).length * 1); + mem.write(0, (byte[]) value, 0, ((byte[]) value).length); + holder = mem; + Count = 0; + field1.writeField("pointerValue", mem); + } else { + throw new IllegalArgumentException(type.name() + " must be set from byte[]"); + } + break; + case EvtVarTypeFileTime: + case EvtVarTypeEvtHandle: + case EvtVarTypeSysTime: + case EvtVarTypeGuid: + case EvtVarTypeSid: + case EvtVarTypeSizeT: + default: + throw new IllegalStateException(String.format("NOT IMPLEMENTED: getValue(%s) (Array: %b, Count: %d)", type, isArray(), Count)); + } + } + write(); + } + + /** + * @return value contained in the EVT_VARIANT + */ + public Object getValue() { + EVT_VARIANT_TYPE type = getVariantType(); + switch (type) { + case EvtVarTypeAnsiString: + return isArray() ? field1.getPointer().getPointer(0).getStringArray(0, Count) : field1.getPointer().getPointer(0).getString(0); + case EvtVarTypeBoolean: + if (isArray()) { + int[] rawValue = field1.getPointer().getPointer(0).getIntArray(0, Count); + WinDef.BOOL[] result = new WinDef.BOOL[rawValue.length]; + for (int i = 0; i < result.length; i++) { + result[i] = new WinDef.BOOL(rawValue[i]); + } + return result; + } else { + return new WinDef.BOOL(field1.getPointer().getInt(0)); + } + case EvtVarTypeString: + case EvtVarTypeEvtXml: + return isArray() ? field1.getPointer().getPointer(0).getWideStringArray(0, Count) : field1.getPointer().getPointer(0).getWideString(0); + case EvtVarTypeFileTime: + if (isArray()) { + WinBase.FILETIME resultFirst = (WinBase.FILETIME) Structure.newInstance(WinBase.FILETIME.class, field1.getPointer().getPointer(0)); + resultFirst.read(); + return resultFirst.toArray(Count); + } else { + WinBase.FILETIME result = new WinBase.FILETIME(field1.getPointer()); + result.read(); + return result; + } + case EvtVarTypeSysTime: + if (isArray()) { + WinBase.SYSTEMTIME resultFirst = (WinBase.SYSTEMTIME) Structure.newInstance(WinBase.SYSTEMTIME.class, field1.getPointer().getPointer(0)); + resultFirst.read(); + return resultFirst.toArray(Count); + } else { + WinBase.SYSTEMTIME result = (WinBase.SYSTEMTIME) Structure.newInstance(WinBase.SYSTEMTIME.class, field1.getPointer().getPointer(0)); + result.read(); + return result; + } + case EvtVarTypeSByte: + case EvtVarTypeByte: + return isArray() ? field1.getPointer().getPointer(0).getByteArray(0, Count) : field1.getPointer().getByte(0); + case EvtVarTypeInt16: + case EvtVarTypeUInt16: + return isArray() ? field1.getPointer().getPointer(0).getShortArray(0, Count) : field1.getPointer().getShort(0); + case EvtVarTypeHexInt32: + case EvtVarTypeInt32: + case EvtVarTypeUInt32: + return isArray() ? field1.getPointer().getPointer(0).getIntArray(0, Count) : field1.getPointer().getInt(0); + case EvtVarTypeHexInt64: + case EvtVarTypeInt64: + case EvtVarTypeUInt64: + return isArray() ? field1.getPointer().getPointer(0).getLongArray(0, Count) : field1.getPointer().getLong(0); + case EvtVarTypeSingle: + return isArray() ? field1.getPointer().getPointer(0).getFloatArray(0, Count) : field1.getPointer().getFloat(0); + case EvtVarTypeDouble: + return isArray() ? field1.getPointer().getPointer(0).getDoubleArray(0, Count) : field1.getPointer().getDouble(0); + case EvtVarTypeBinary: + assert (!isArray()); + return field1.getPointer().getPointer(0).getByteArray(0, Count); + case EvtVarTypeNull: + return null; + case EvtVarTypeGuid: + if (isArray()) { + Guid.GUID resultFirst = (Guid.GUID) Structure.newInstance(Guid.GUID.class, field1.getPointer().getPointer(0)); + resultFirst.read(); + return resultFirst.toArray(Count); + } else { + Guid.GUID result = (Guid.GUID) Structure.newInstance(Guid.GUID.class, field1.getPointer().getPointer(0)); + result.read(); + return result; + } + case EvtVarTypeSid: + if (isArray()) { + WinNT.PSID resultFirst = (WinNT.PSID) Structure.newInstance(WinNT.PSID.class, field1.getPointer().getPointer(0)); + resultFirst.read(); + return resultFirst.toArray(Count); + } else { + WinNT.PSID result = (WinNT.PSID) Structure.newInstance(WinNT.PSID.class, field1.getPointer().getPointer(0)); + result.read(); + return result; + } + case EvtVarTypeSizeT: + if (isArray()) { + long[] rawValue = field1.getPointer().getPointer(0).getLongArray(0, Count); + BaseTSD.SIZE_T[] result = new BaseTSD.SIZE_T[rawValue.length]; + for (int i = 0; i < result.length; i++) { + result[i] = new BaseTSD.SIZE_T(rawValue[i]); + } + return result; + } else { + return new BaseTSD.SIZE_T(field1.getPointer().getLong(0)); + } + case EvtVarTypeEvtHandle: + if (isArray()) { + Pointer[] rawValue = field1.getPointer().getPointer(0).getPointerArray(0, Count); + WinNT.HANDLE[] result = new WinNT.HANDLE[rawValue.length]; + for (int i = 0; i < result.length; i++) { + result[i] = new WinNT.HANDLE(rawValue[i]); + } + return result; + } else { + return new WinNT.HANDLE(field1.getPointer().getPointer(0)); + } + default: + throw new IllegalStateException(String.format("NOT IMPLEMENTED: getValue(%s) (Array: %b, Count: %d)", type, isArray(), Count)); + } + } + } + + /** + * Defines the types of authentication that you can use to authenticate the user when connecting to a remote + * computer. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385570(v=vs.85).aspx + */ + public static interface EVT_RPC_LOGIN_FLAGS { + + /** + * Use the default authentication method during RPC login. The default authentication method is Negotiate. + */ + public static final int EvtRpcLoginAuthDefault = 0; + + /** + * Use the Negotiate authentication method during RPC login. The client and server negotiate whether to use + * NTLM or Kerberos. + */ + public static final int EvtRpcLoginAuthNegotiate = 1; + + /** Use Kerberos authentication during RPC login. */ + public static final int EvtRpcLoginAuthKerberos = 2; + + /** Use NTLM authentication during RPC login. */ + public static final int EvtRpcLoginAuthNTLM = 3; + } + + /** + * Contains the information used to connect to a remote computer. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385566(v=vs.85).aspx + */ + public class EVT_RPC_LOGIN extends Structure { + + /** The name of the remote computer to connect to. */ + public String Server; + + /** The user name to use to connect to the remote computer. */ + public String User; + + /** The domain to which the user account belongs. Optional. */ + public String Domain; + + /** The password for the user account. */ + public String Password; + + /** + * The authentication method to use to authenticate the user when connecting to the remote computer. + * For possible authentication methods, see the {@link Winevt.EVT_RPC_LOGIN_FLAGS} enumeration. + */ + public int Flags; + + public EVT_RPC_LOGIN() { + super(W32APITypeMapper.UNICODE); + } + + protected List getFieldOrder() { + return Arrays.asList("Server", "User", "Domain", "Password", "Flags"); + } + + public EVT_RPC_LOGIN(String Server, String User, String Domain, String Password, int Flags) { + super(W32APITypeMapper.UNICODE); + this.Server = Server; + this.User = User; + this.Domain = Domain; + this.Password = Password; + this.Flags = Flags; + } + + public EVT_RPC_LOGIN(Pointer peer) { + super(peer, Structure.ALIGN_DEFAULT, W32APITypeMapper.UNICODE); + } + + public static class ByReference extends EVT_RPC_LOGIN implements Structure.ByReference { + + } + + public static class ByValue extends EVT_RPC_LOGIN implements Structure.ByValue { + + } + } + + /** + * Defines the values that specify how to return the query results and whether you are query against a channel or + * log file. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385549(v=vs.85).aspx + */ + public static interface EVT_QUERY_FLAGS { + + /** + * Specifies that the query is against one or more channels. The Path parameter of the EvtQuery function must + * specify the name of a channel or NULL. + */ + public static final int EvtQueryChannelPath = 0x1; + + /** + * Specifies that the query is against one or more log files. The Path parameter of the EvtQuery function must + * specify the full path to a log file or NULL. + */ + public static final int EvtQueryFilePath = 0x2; + + /** + * Specifies that the events in the query result are ordered from oldest to newest. This is the default. + */ + public static final int EvtQueryForwardDirection = 0x100; + + /** + * Specifies that the events in the query result are ordered from newest to oldest. + */ + public static final int EvtQueryReverseDirection = 0x200; + + /** + * Specifies that {@link Wevtapi#EvtQuery} should run the query even if the part of the query generates + * an error (is not well formed). The service validates the syntax of the XPath query to determine if it is + * well formed. If the validation fails, the service parses the XPath into individual expressions. It builds + * a new XPath beginning with the left most expression. The service validates the expression and if it is valid, + * the service adds the next expression to the XPath. The service repeats this process until it finds + * the expression that is failing. It then uses the valid expressions that it found beginning with the leftmost + * expression as the XPath query (which means that you may not get the events that you expected). If no part of + * the XPath is valid, the EvtQuery call fails. + */ + public static final int EvtQueryTolerateQueryErrors = 0x1000; + } + + /** + * Defines the relative position in the result set from which to seek. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385575(v=vs.85).aspx + */ + public static interface EVT_SEEK_FLAGS { + + /** + * Seek to the specified offset from the first entry in the result set. The offset must be a positive value. + */ + public static final int EvtSeekRelativeToFirst = 1; + + /** + * Seek to the specified offset from the last entry in the result set. The offset must be a negative value. + */ + public static final int EvtSeekRelativeToLast = 2; + + /** + * Seek to the specified offset from the current entry in the result set. The offset can be a positive or + * negative value. + */ + public static final int EvtSeekRelativeToCurrent = 3; + + /** + * Seek to the specified offset from the bookmarked entry in the result set. The offset can be a positive or + * negative value. + */ + public static final int EvtSeekRelativeToBookmark = 4; + + /** + * A bitmask that you can use to determine which of the following flags is set: + *

      + *
    • EvtSeekRelativeToFirst
    • + *
    • EvtSeekRelativeToLast
    • + *
    • EvtSeekRelativeToBookmark
    • + *
    + */ + public static final int EvtSeekOriginMask = 7; + + /** + * Force the function to fail if the event does not exist. + */ + public static final int EvtSeekStrict = 0x10000; + } + + /** + * Defines the possible values that specify when to start subscribing to events. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385588(v=vs.85).aspx + */ + public static interface EVT_SUBSCRIBE_FLAGS { + + /** + * Subscribe to only future events that match the query criteria. + */ + public static final int EvtSubscribeToFutureEvents = 1; + + /** + * Subscribe to all existing and future events that match the query criteria. + */ + public static final int EvtSubscribeStartAtOldestRecord = 2; + + /** + * Subscribe to all existing and future events that match the query criteria that begin after the bookmarked + * event. If you include the EvtSubscribeStrict flag, the {@link Wevtapi#EvtSubscribe} function fails if + * the bookmarked event does not exist. If you do not include the EvtSubscribeStrict flag and the bookmarked + * event does not exist, the subscription begins with the event that is after the event that is closest to + * the bookmarked event. + */ + public static final int EvtSubscribeStartAfterBookmark = 3; + + /** + * A bitmask that you can use to determine which of the following flags is set: + *
      + *
    • EvtSubscribeToFutureEvents
    • + *
    • EvtSubscribeStartAtOldestRecord
    • + *
    • EvtSubscribeStartAfterBookmark
    • + *
    + */ + public static final int EvtSubscribeOriginMask = 3; + + /** + * Complete the subscription even if the part of the query generates an error (is not well formed). The service + * validates the syntax of the XPath query to determine if it is well formed. If the validation fails, + * the service parses the XPath into individual expressions. It builds a new XPath beginning with the left most + * expression. The service validates the expression and if it is valid, the service adds the next expression to + * the XPath. The service repeats this process until it finds the expression that is failing. It then uses + * the valid expressions that it found beginning with the leftmost expression as the XPath query (which means + * that you may not get the events that you expected). If no part of the XPath is valid, + * the {@link Wevtapi#EvtSubscribe} call fails. + */ + public static final int EvtSubscribeTolerateQueryErrors = 0x1000; + + /** + * Forces the {@link Wevtapi#EvtSubscribe} call to fail if you specify EvtSubscribeStartAfterBookmark and + * the bookmarked event is not found (the return value is ERROR_NOT_FOUND). Also, set this flag if you want to + * receive notification in your callback when event records are missing. + */ + public static final int EvtSubscribeStrict = 0x10000; + } + + /** + * Defines the possible types of data that the subscription service can deliver to your callback. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385596(v=vs.85).aspx + */ + public static interface EVT_SUBSCRIBE_NOTIFY_ACTION { + + /** + * Indicates that the Event parameter contains a Win32 error code. + */ + public static final int EvtSubscribeActionError = 0; + + /** + * Indicates that the Event parameter contains an event that matches the subscriber's query. + */ + public static final int EvtSubscribeActionDeliver = 1; + } + + /** + * Defines the identifiers that identify the system-specific properties of an event. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385606(v=vs.85).aspx + */ + public static interface EVT_SYSTEM_PROPERTY_ID { + + /** + * Identifies the Name attribute of the provider element. The variant type for this property is EvtVarTypeString. + */ + public static final int EvtSystemProviderName = 0; + + /** + * Identifies the Guid attribute of the provider element. The variant type for this property is EvtVarTypeGuid. + */ + public static final int EvtSystemProviderGuid = 1; + + /** Identifies the EventID element. The variant type for this property is EvtVarTypeUInt16. */ + public static final int EvtSystemEventID = 2; + + /** + * Identifies the Qualifiers attribute of the EventID element. The variant type for this property is + * EvtVarTypeUInt16. + */ + public static final int EvtSystemQualifiers = 3; + + /** Identifies the Level element. The variant type for this property is EvtVarTypeUInt8. */ + public static final int EvtSystemLevel = 4; + + /** Identifies the Task element. The variant type for this property is EvtVarTypeUInt16. */ + public static final int EvtSystemTask = 5; + + /** Identifies the Opcode element. The variant type for this property is EvtVarTypeUInt8. */ + public static final int EvtSystemOpcode = 6; + + /** Identifies the Keywords element. The variant type for this property is EvtVarTypeInt64. */ + public static final int EvtSystemKeywords = 7; + + /** + * Identifies the SystemTime attribute of the TimeCreated element. The variant type for this property is + * EvtVarTypeFileTime. + */ + public static final int EvtSystemTimeCreated = 8; + + /** Identifies the EventRecordID element. The variant type for this property is EvtVarTypeUInt64. */ + public static final int EvtSystemEventRecordId = 9; + + /** + * Identifies the ActivityID attribute of the Correlation element. The variant type for this property is + * EvtVarTypeGuid. + */ + public static final int EvtSystemActivityID = 10; + + /** + * Identifies the RelatedActivityID attribute of the Correlation element. The variant type for this property is + * EvtVarTypeGuid. + */ + public static final int EvtSystemRelatedActivityID = 11; + + /** + * Identifies the ProcessID attribute of the Execution element. The variant type for this property is + * EvtVarTypeUInt32. + */ + public static final int EvtSystemProcessID = 12; + + /** + * Identifies the ThreadID attribute of the Execution element. The variant type for this property is + * EvtVarTypeUInt32. + */ + public static final int EvtSystemThreadID = 13; + + /** Identifies the Channel element. The variant type for this property is EvtVarTypeString. */ + public static final int EvtSystemChannel = 14; + + /** Identifies the Computer element. The variant type for this property is EvtVarTypeString. */ + public static final int EvtSystemComputer = 15; + + /** Identifies the UserID element. The variant type for this property is EvtVarTypeSid. */ + public static final int EvtSystemUserID = 16; + + /** Identifies the Version element. The variant type for this property is EvtVarTypeUInt8. */ + public static final int EvtSystemVersion = 17; + + /** This enumeration value marks the end of the enumeration values. */ + public static final int EvtSystemPropertyIdEND = 18; + } + + /** + * Defines the values that specify the type of information to access from the event. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385561(v=vs.85).aspx + */ + public static interface EVT_RENDER_CONTEXT_FLAGS { + + /** Render specific properties from the event. */ + public static final int EvtRenderContextValues = 0; + + /** + * Render the system properties under the System element. The properties are returned in the order defined in + * the {@link EVT_SYSTEM_PROPERTY_ID} enumeration. + */ + public static final int EvtRenderContextSystem = 1; + + /** + * Render all user-defined properties under the UserData or EventData element. If the data template associated + * with the event contains a UserData section, the UserData properties are rendered; otherwise, the EventData + * properties are rendered. + */ + public static final int EvtRenderContextUser = 2; + } + + /** + * Defines the values that specify what to render. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385563(v=vs.85).aspx + */ + public static interface EVT_RENDER_FLAGS { + + /** Render the event properties specified in the rendering context. */ + public static final int EvtRenderEventValues = 0; + + /** + * Render the event as an XML string. For details on the contents of the XML string, see the Event schema. + */ + public static final int EvtRenderEventXml = 1; + + /** + * Render the bookmark as an XML string, so that you can easily persist the bookmark for use later. + */ + public static final int EvtRenderBookmark = 2; + } + + /** + * Defines the values that specify the message string from the event to format. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385525(v=vs.85).aspx + */ + public static interface EVT_FORMAT_MESSAGE_FLAGS { + + /** Format the event's message string. */ + public static final int EvtFormatMessageEvent = 1; + + /** Format the message string of the level specified in the event. */ + public static final int EvtFormatMessageLevel = 2; + + /** Format the message string of the task specified in the event. */ + public static final int EvtFormatMessageTask = 3; + + /** Format the message string of the opcode specified in the event. */ + public static final int EvtFormatMessageOpcode = 4; + + /** + * Format the message string of the keywords specified in the event. If the event specifies multiple keywords, + * the formatted string is a list of null-terminated strings. Increment through the strings until your pointer + * points past the end of the used buffer. + */ + public static final int EvtFormatMessageKeyword = 5; + + /** Format the message string of the channel specified in the event. */ + public static final int EvtFormatMessageChannel = 6; + + /** Format the provider's message string. */ + public static final int EvtFormatMessageProvider = 7; + + /** + * Format the message string associated with a resource identifier. The provider's metadata contains + * the resource identifiers; the message compiler assigns a resource identifier to each string when it compiles + * the manifest. + */ + public static final int EvtFormatMessageId = 8; + + /** + * Format all the message strings in the event. The formatted message is an XML string that contains the event + * details and the message strings. The message strings are included in the RenderingInfo section of the event + * details. + */ + public static final int EvtFormatMessageXml = 9; + } + + /** + * Defines the values that specify whether to open a channel or exported log file. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385541(v=vs.85).aspx + */ + public static interface EVT_OPEN_LOG_FLAGS { + + /** Open a channel. */ + public static final int EvtOpenChannelPath = 0x1; + + /** Open an exported log file. */ + public static final int EvtOpenFilePath = 0x2; + } + + /** + * Defines the identifiers that identify the log file metadata properties of a channel or log file. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385536(v=vs.85).aspx + */ + public static interface EVT_LOG_PROPERTY_ID { + + /** + * Identifies the property that contains the time that the channel or log file was created. The variant type + * for this property is EvtVarTypeFileTime. + */ + public static final int EvtLogCreationTime = 0; + + /** + * Identifies the property that contains the last time that the channel or log file was accessed. The variant + * type for this property is EvtVarTypeFileTime. + */ + public static final int EvtLogLastAccessTime = 1; + + /** + * Identifies the property that contains the last time that the channel or log file was written to. The variant + * type for this property is EvtVarTypeFileTime. + */ + public static final int EvtLogLastWriteTime = 2; + + /** + * Identifies the property that contains the size of the file, in bytes. The variant type for this property + * is EvtVarTypeUInt64. + */ + public static final int EvtLogFileSize = 3; + + /** + * Identifies the property that contains the file attributes (for details on the file attributes, + * see the GetFileAttributesEx function). The variant type for this property is EvtVarTypeUInt32. + */ + public static final int EvtLogAttributes = 4; + + /** + * Identifies the property that contains the number of records in the channel or log file. The variant type + * for this property is EvtVarTypeUInt64. + */ + public static final int EvtLogNumberOfLogRecords = 5; + + /** + * Identifies the property that contains the record number of the oldest event in the channel or log file. + * The variant type for this property is EvtVarTypeUInt64. + */ + public static final int EvtLogOldestRecordNumber = 6; + + /** + * Identifies the property that you use to determine whether the channel or log file is full. The variant type + * for this property is EvtVarTypeBoolean. The channel is full if another event cannot be written to the channel + * (for example, if the channel is sequential and maximum size is reached). The property will always be false if + * the channel is circular or the sequential log is automatically backed up. + */ + public static final int EvtLogFull = 7; + } + + /** + * Defines values that indicate whether the events come from a channel or log file. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385522(v=vs.85).aspx + */ + public static interface EVT_EXPORTLOG_FLAGS { + + /** The source of the events is a channel. */ + public static final int EvtExportLogChannelPath = 0x1; + + /** The source of the events is a previously exported log file. */ + public static final int EvtExportLogFilePath = 0x2; + + /** + * Export events even if part of the query generates an error (is not well formed). The service validates + * the syntax of the XPath query to determine whether it is well formed. If the validation fails, the service + * parses the XPath into individual expressions. It builds a new XPath beginning with the leftmost expression. + * The service validates the expression and if it is valid, the service adds the next expression to the XPath. + * The service repeats this process until it finds the expression that is failing. It then uses the valid + * expressions as the XPath query (which means that you may not get the events that you expected). If no part of + * the XPath is valid, the EvtExportLog call fails. + */ + public static final int EvtExportLogTolerateQueryErrors = 0x1000; + + /** no document */ + public static final int EvtExportLogOverwrite = 0x2000; + } + + /** + * Defines the identifiers that identify the configuration properties of a channel. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385499(v=vs.85).aspx + */ + public static interface EVT_CHANNEL_CONFIG_PROPERTY_ID { + + /** + * Identifies the enabled attribute of the channel. The variant type for this property is EvtVarTypeBoolean. + * You cannot set this property for the Application, System, and Security channels. + */ + public static final int EvtChannelConfigEnabled = 0; + + /** + * Identifies the isolation attribute of the channel. The variant type for this property is EvtVarTypeUInt32. + * For possible isolation values, see the {@link Winevt.EVT_CHANNEL_ISOLATION_TYPE} enumeration. + * You cannot set this property for the Application, System, and Security channels. + */ + public static final int EvtChannelConfigIsolation = 1; + + /** + * Identifies the type attribute of the channel. The variant type for this property is EvtVarTypeUInt32. + * For possible isolation values, see the {@link Winevt.EVT_CHANNEL_TYPE} enumeration. + * You cannot set this property. + */ + public static final int EvtChannelConfigType = 2; + + /** + * Identifies the name attribute of the provider that defined the channel. The variant type for this property + * is EvtVarTypeString. You cannot set this property. + */ + public static final int EvtChannelConfigOwningPublisher = 3; + + /** + * Identifies the configuration property that indicates whether the channel is a classic event channel + * (for example the Application or System log). The variant type for this property is EvtVarTypeBoolean. + * You cannot set this property. + */ + public static final int EvtChannelConfigClassicEventlog = 4; + + /** + * Identifies the access attribute of the channel. The variant type for this property is EvtVarTypeString. + */ + public static final int EvtChannelConfigAccess = 5; + + /** + * Identifies the retention logging attribute of the channel. The variant type for this property is + * EvtVarTypeBoolean. + */ + public static final int EvtChannelLoggingConfigRetention = 6; + + /** + * Identifies the autoBackup logging attribute of the channel. The variant type for this property is + * EvtVarTypeBoolean. + */ + public static final int EvtChannelLoggingConfigAutoBackup = 7; + + /** + * Identifies the maxSize logging attribute of the channel. The variant type for this property is + * EvtVarTypeUInt64. + */ + public static final int EvtChannelLoggingConfigMaxSize = 8; + + /** + * Identifies the configuration property that contains the path to the file that backs the channel. + * The variant type for this property is EvtVarTypeString. + */ + public static final int EvtChannelLoggingConfigLogFilePath = 9; + + /** + * Identifies the level publishing attribute of the channel. The variant type for this property is + * EvtVarTypeUInt32. + * To set this property, you must first disable the debug or analytic channel. + */ + public static final int EvtChannelPublishingConfigLevel = 10; + + /** + * Identifies the keywords publishing attribute of the channel. The variant type for this property is + * EvtVarTypeUInt64. + * To set this property, you must first disable the debug or analytic channel. + */ + public static final int EvtChannelPublishingConfigKeywords = 11; + + /** + * Identifies the controlGuid publishing attribute of the channel. The variant type for this property is + * EvtVarTypeGuid. + * You cannot set this property. + */ + public static final int EvtChannelPublishingConfigControlGuid = 12; + + /** + * Identifies the bufferSize publishing attribute of the channel. The variant type for this property is + * EvtVarTypeUInt32. + * You cannot set this property. + */ + public static final int EvtChannelPublishingConfigBufferSize = 13; + + /** + * Identifies the minBuffers publishing attribute of the channel. The variant type for this property is + * EvtVarTypeUInt32. You cannot set this property. + */ + public static final int EvtChannelPublishingConfigMinBuffers = 14; + + /** + * Identifies the maxBuffers publishing attribute of the channel. The variant type for this property is + * EvtVarTypeUInt32. + * You cannot set this property. + */ + public static final int EvtChannelPublishingConfigMaxBuffers = 15; + + /** + * Identifies the latency publishing attribute of the channel. The variant type for this property is + * EvtVarTypeUInt32. + * You cannot set this property. + */ + public static final int EvtChannelPublishingConfigLatency = 16; + + /** + * Identifies the clockType publishing attribute of the channel. The variant type for this property is + * EvtVarTypeUInt32. For possible clock type values, see the {@link Winevt.EVT_CHANNEL_CLOCK_TYPE} enumeration. + * You cannot set this property. + */ + public static final int EvtChannelPublishingConfigClockType = 17; + + /** + * Identifies the sidType publishing attribute of the channel. The variant type for this property is + * EvtVarTypeUInt32. For possible SID type values, see the {@link Winevt.EVT_CHANNEL_SID_TYPE} enumeration. + * You cannot set this property. + */ + public static final int EvtChannelPublishingConfigSidType = 18; + + /** + * Identifies the configuration property that contains the list of providers that import this channel. + * The variant type for this property is EvtVarTypeString | EVT_VARIANT_TYPE_ARRAY. + * You cannot set this property. + */ + public static final int EvtChannelPublisherList = 19; + + /** + * Identifies the fileMax publishing attribute of the channel. The variant type for this property is + * EvtVarTypeUInt32. + */ + public static final int EvtChannelPublishingConfigFileMax = 20; + + /** + * This enumeration value marks the end of the enumeration values. + */ + public static final int EvtChannelConfigPropertyIdEND = 21; + } + + /** + * Defines the type of a channel. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385514(v=vs.85).aspx + */ + public static interface EVT_CHANNEL_TYPE { + + /** The channel's type is Admin. */ + public static final int EvtChannelTypeAdmin = 0; + + /** The channel's type is Operational. */ + public static final int EvtChannelTypeOperational = 1; + + /** The channel's type is Analytic. */ + public static final int EvtChannelTypeAnalytic = 2; + + /** The channel's type is Debug. */ + public static final int EvtChannelTypeDebug = 3; + } + + /** + * Defines the default access permissions to apply to the channel. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385502(v=vs.85).aspx + */ + public static interface EVT_CHANNEL_ISOLATION_TYPE { + + /** Provides open access to the channel. */ + public static final int EvtChannelIsolationTypeApplication = 0; + + /** + * Provides restricted access to the channel and is used by applications running under system service accounts, + * drivers, or an application that logs events that relate to the health of the computer. + */ + public static final int EvtChannelIsolationTypeSystem = 1; + + /** Provides custom access to the channel. */ + public static final int EvtChannelIsolationTypeCustom = 2; + } + + /** + * Defines the values that specify the type of time stamp to use when logging events channel. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385493(v=vs.85).aspx + */ + public static interface EVT_CHANNEL_CLOCK_TYPE { + + /** + * Uses the system time for the time stamp. The system time provides a low-resolution (10 milliseconds) time + * stamp but is comparatively less expensive to retrieve. System time is the default. Note that if the volume + * of events is high, the resolution for system time may not be fine enough to determine the sequence of events. + * If multiple events contain the same time stamp, the events may be delivered in the wrong order. + */ + public static final int EvtChannelClockTypeSystemTime = 0; + + /** + * Uses the query performance counter (QPC) for the time stamp. The QPC time stamp provides a high-resolution + * (100 nanoseconds) time stamp but is comparatively more expensive to retrieve. You should use this resolution + * if you have high event rates or if the consumer merges events from different buffers. Note that on older + * computers, the time stamp may not be accurate because the counter sometimes skips forward due to hardware + * errors. + */ + public static final int EvtChannelClockTypeQPC = 1; + } + + /** + * Defines the values that determine whether the event includes the security identifier (SID) of the principal + * that logged the event. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385511(v=vs.85).aspx + */ + public static interface EVT_CHANNEL_SID_TYPE { + + /** Do not include with the event the SID of the principal that logged the event. */ + public static final int EvtChannelSidTypeNone = 0; + + /** Include with the event the SID of the principal that logged the event. */ + public static final int EvtChannelSidTypePublishing = 1; + } + + /** + * Defines the values that specify how a channel is referenced. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385507(v=vs.85).aspx + */ + public static interface EVT_CHANNEL_REFERENCE_FLAGS { + + /** Specifies that the channel is imported. */ + public static final int EvtChannelReferenceImported = 0x1; + } + + /** + * Defines the identifiers that identify the metadata properties of a provider. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385545(v=vs.85).aspx + */ + public static interface EVT_PUBLISHER_METADATA_PROPERTY_ID { + + /** + * Identifies the guid attribute of the provider. The variant type for this property is EvtVarTypeGuid. + */ + public static final int EvtPublisherMetadataPublisherGuid = 0; + + /** + * Identifies the resourceFilePath attribute of the provider. The variant type for this property is + * EvtVarTypeString. + */ + public static final int EvtPublisherMetadataResourceFilePath = 1; + + /** + * Identifies the parameterFilePath attribute of the provider. The variant type for this property is + * EvtVarTypeString. + */ + public static final int EvtPublisherMetadataParameterFilePath = 2; + + /** + * Identifies the messageFilePath attribute of the provider. The variant type for this property is + * EvtVarTypeString. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385545(v=vs.85).aspx + */ + public static final int EvtPublisherMetadataMessageFilePath = 3; + + /** + * Identifies the helpLink attribute of the provider. The variant type for this property is EvtVarTypeString. + */ + public static final int EvtPublisherMetadataHelpLink = 4; + + /** + * Identifies the message attribute of the provider. The metadata is the resource identifier assigned to + * the message string. To get the message string, call the {@link Wevtapi#EvtFormatMessage} function. + * The variant type for this property is EvtVarTypeUInt32. If the provider does not specify a message, + * the value is -1. + */ + public static final int EvtPublisherMetadataPublisherMessageID = 5; + + /** + * Identifies the channels child element of the provider. The variant type for this property is + * EvtVarTypeEvtHandle. To access the metadata of the channels that the provider defines or imports, use this + * handle when calling the {@link Wevtapi#EvtGetObjectArrayProperty} function. For details, see Remarks. + * When you are done with the handle, call the {@link Wevtapi#EvtClose} function. + */ + public static final int EvtPublisherMetadataChannelReferences = 6; + + /** + * Identifies the name attribute of the channel. Use this identifier when calling + * the {@link Wevtapi#EvtGetObjectArrayProperty} function. For details, see Remarks. The variant type for + * this property is EvtVarTypeString. + */ + public static final int EvtPublisherMetadataChannelReferencePath = 7; + + /** + * Identifies the zero-based index value of the channel in the list of channels. Use this identifier when + * calling the {@link Wevtapi#EvtGetObjectArrayProperty} function. For details, see Remarks. The variant type + * for this property is EvtVarTypeUInt32. + */ + public static final int EvtPublisherMetadataChannelReferenceIndex = 8; + + /** + * Identifies the value attribute of the channel. Use this identifier when calling + * the ${@link Wevtapi#EvtGetObjectArrayProperty} function. For details, see Remarks. The variant type for + * this property is EvtVarTypeUInt32. + */ + public static final int EvtPublisherMetadataChannelReferenceID = 9; + + /** + * Identifies the flags value that indicates whether this channel is imported from another provider. The channel + * is imported if the EvtChannelReferenceImported flag value is set. Use this identifier when calling + * the {@link Wevtapi#EvtGetObjectArrayProperty} function. For details, see Remarks. + * The variant type for this property is EvtVarTypeUInt32. + */ + public static final int EvtPublisherMetadataChannelReferenceFlags = 10; + + /** + * Identifies the message attribute of the channel. Use this identifier when calling + * the {@link Wevtapi#EvtGetObjectArrayProperty} function. For details, see Remarks. The variant type for + * this property is EvtVarTypeUInt32. The property contains the resource identifier that is assigned to + * the message string. To get the message string, call the EvtFormatMessage function. + * If the channel does not specify a message, the value is -1. + */ + public static final int EvtPublisherMetadataChannelReferenceMessageID = 11; + + /** + * Identifies the levels child element of the provider. The variant type for this property is + * EvtVarTypeEvtHandle. To access the metadata of the levels that the provider defines or references, + * use this handle when calling the {@link Wevtapi#EvtGetObjectArrayProperty} function. For details, + * see Remarks. When you are done with the handle, call the {@link Wevtapi#EvtClose} function. + */ + public static final int EvtPublisherMetadataLevels = 12; + + /** + * Identifies the name attribute of the level. Use this identifier when calling + * the {@link Wevtapi#EvtGetObjectArrayProperty} function. For details, see Remarks. + * The variant type for this property is EvtVarTypeString. + */ + public static final int EvtPublisherMetadataLevelName = 13; + + /** + * Identifies the value attribute of the level. Use this identifier when calling + * the {@link Wevtapi#EvtGetObjectArrayProperty} function. For details, see Remarks. The variant type for + * this property is EvtVarTypeUInt32. + */ + public static final int EvtPublisherMetadataLevelValue = 14; + + /** + * Identifies the message attribute of the level. Use this identifier when calling + * the {@link Wevtapi#EvtGetObjectArrayProperty} function. For details, see Remarks. The variant type for + * this property is EvtVarTypeUInt32. The property contains the resource identifier that is assigned to + * the message string. To get the message string, call the {@link Wevtapi#EvtFormatMessage} function. + * If the level does not specify a message, the value is -1. + */ + public static final int EvtPublisherMetadataLevelMessageID = 15; + + /** + * Identifies the tasks child element of the provider. The variant type for this property is + * EvtVarTypeEvtHandle. To access the metadata of the tasks that the provider defines, use this handle when + * calling the {@link Wevtapi#EvtGetObjectArrayProperty} function. For details, see Remarks. + * When you are done with the handle, call the {@link Wevtapi#EvtClose} function. + */ + public static final int EvtPublisherMetadataTasks = 16; + + /** + * Identifies the name attribute of the task. Use this identifier when calling + * the {@link Wevtapi#EvtGetObjectArrayProperty} function. For details, see Remarks. + * The variant type for this property is EvtVarTypeString. + */ + public static final int EvtPublisherMetadataTaskName = 17; + + /** + * Identifies the eventGuid attribute of the task. Use this identifier when calling + * the {@link Wevtapi#EvtGetObjectArrayProperty} function. For details, see Remarks. + * The variant type for this property is EvtVarTypeString. + */ + public static final int EvtPublisherMetadataTaskEventGuid = 18; + + /** + * Identifies the value attribute of the task. Use this identifier when calling + * the {@link Wevtapi#EvtGetObjectArrayProperty} function. For details, see Remarks. + * The variant type for this property is EvtVarTypeUInt32. + */ + public static final int EvtPublisherMetadataTaskValue = 19; + + /** + * Identifies the message attribute of the task. Use this identifier when calling + * the {@link Wevtapi#EvtGetObjectArrayProperty} function. For details, see Remarks. + * The variant type for this property is EvtVarTypeUInt32. The property contains the resource identifier + * that is assigned to the message string. To get the message string, call the {@link Wevtapi#EvtFormatMessage} + * function. If the task does not specify a message, the value is -1. + */ + public static final int EvtPublisherMetadataTaskMessageID = 20; + + /** + * Identifies the opcodes child element of the provider. The variant type for this property is + * EvtVarTypeEvtHandle. To access the metadata of the opcodes that the provider defines or references, + * use this handle when calling the {@link Wevtapi#EvtGetObjectArrayProperty} function. For details, + * see Remarks. When you are done with the handle, call the {@link Wevtapi#EvtClose} function. + */ + public static final int EvtPublisherMetadataOpcodes = 21; + + /** + * Identifies the name attribute of the opcode. Use this identifier when calling + * the {@link Wevtapi#EvtGetObjectArrayProperty} function. For details, see Remarks. + * The variant type for this property is EvtVarTypeString. + */ + public static final int EvtPublisherMetadataOpcodeName = 22; + + /** + * Identifies the value attribute of the opcode. Use this identifier when calling + * the {@link Wevtapi#EvtGetObjectArrayProperty} function. For details, see Remarks. The variant type for + * this property is EvtVarTypeUInt32. The high word contains the opcode value and the low word contains the task + * to which it belongs. If the low word is zero, the opcode is defined globally; otherwise, the opcode is task + * specific. Use the low word value to determine the task that defines the opcode. + */ + public static final int EvtPublisherMetadataOpcodeValue = 23; + + /** + * Identifies the message attribute of the opcode. Use this identifier when calling + * the {@link Wevtapi#EvtGetObjectArrayProperty} function. For details, see Remarks. The variant type for + * this property is EvtVarTypeUInt32. The property contains the resource identifier that is assigned to + * the message string. To get the message string, call the {@link Wevtapi#EvtFormatMessage} function. + * If the opcode does not specify a message, the value is -1. + */ + public static final int EvtPublisherMetadataOpcodeMessageID = 24; + + /** + * Identifies the keywords child element of the provider. The variant type for this property is + * EvtVarTypeEvtHandle. To access the metadata of the keywords that the provider defines, use this handle when + * calling the {@link Wevtapi#EvtGetObjectArrayProperty} function. For details, see Remarks. When you are done + * with the handle, call the {@link Wevtapi#EvtClose} function. + */ + public static final int EvtPublisherMetadataKeywords = 25; + + /** + * Identifies the name attribute of the keyword. Use this identifier when calling + * the {@link Wevtapi#EvtGetObjectArrayProperty} function. For details, see Remarks. + * The variant type for this property is EvtVarTypeString. + */ + public static final int EvtPublisherMetadataKeywordName = 26; + + /** + * Identifies the mask attribute of the keyword. Use this identifier when calling + * the {@link Wevtapi#EvtGetObjectArrayProperty} function. For details, see Remarks. + * The variant type for this property is EvtVarTypeUInt64. + */ + public static final int EvtPublisherMetadataKeywordValue = 27; + + /** + * Identifies the message attribute of the keyword. Use this identifier when calling + * the {@link Wevtapi#EvtGetObjectArrayProperty} function. For details, see Remarks. The variant type for + * this property is EvtVarTypeUInt32. The property contains the resource identifier that is assigned to + * the message string. To get the message string, call the {@link Wevtapi#EvtFormatMessage} function. + * If the keyword does not specify a message, the value is -1. + */ + public static final int EvtPublisherMetadataKeywordMessageID = 28; + + /** This enumeration value marks the end of the enumeration values. */ + public static final int EvtPublisherMetadataPropertyIdEND = 29; + } + + /** + * Defines the identifiers that identify the metadata properties of an event definition. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385517%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396 + */ + public static interface EVT_EVENT_METADATA_PROPERTY_ID { + + /** + * Identifies the value attribute of the event definition. The variant type for this property is + * EvtVarTypeUInt32. + */ + public static final int EventMetadataEventID = 0; + + /** + * Identifies the version attribute of the event definition. The variant type for this property is + * EvtVarTypeUInt32. + */ + public static final int EventMetadataEventVersion = 1; + + /** + * Identifies the channel attribute of the event definition. The variant type for this property is + * EvtVarTypeUInt32. This property does not contain the channel identifier that you specified in the event + * definition but instead contains the value attribute of the channel. The value is zero if the event + * definition does not specify a channel. + */ + public static final int EventMetadataEventChannel = 2; + + /** + * Identifies the level attribute of the event definition. The variant type for this property is + * EvtVarTypeUInt32. This property does not contain the level name that you specified in the event definition + * but instead contains the value attribute of the level. The value is zero if the event definition does not + * specify a level. + */ + public static final int EventMetadataEventLevel = 3; + + /** + * Identifies the opcode attribute of the event definition. The variant type for this property is + * EvtVarTypeUInt32. This property does not contain the opcode name that you specified in the event definition + * but instead contains the value attribute of the opcode. The value is zero if the event definition does not + * specify an opcode. + */ + public static final int EventMetadataEventOpcode = 4; + + /** + * dentifies the task attribute of the event definition. The variant type for this property is EvtVarTypeUInt32. + * This property does not contain the task name that you specified in the event definition but instead contains + * the value attribute of the task. The value is zero if the event definition does not specify a task. + */ + public static final int EventMetadataEventTask = 5; + + /** + * Identifies the keyword attribute of the event definition. The variant type for this property is + * EvtVarTypeUInt64. This property does not contain the list of keyword names that you specified in the event + * definition but instead contains a 64-bitmask of all the keywords. The top 16 bits of the mask are reserved + * for internal use and should be ignored when determining the keyword bits that the event definition set. + */ + public static final int EventMetadataEventKeyword = 6; + + /** + * Identifies the message attribute of the event definition. The variant type for this property is + * EvtVarTypeUInt32. The property contains the resource identifier that is assigned to the message string. + * To get the message string, call the EvtFormatMessage function. If the event definition does not specify + * a message, the value is -1. + */ + public static final int EventMetadataEventMessageID = 7; + + /** + * Identifies the template attribute of the event definition. The variant type for this property is + * EvtVarTypeString. This property does not contain the template name that you specified in the event definition + * but instead contains an XML string that includes the template node and each data node; the string does not + * include the UserData. The value is an empty string if the event definition does not specify a template. + */ + public static final int EventMetadataEventTemplate = 8; + + /** This enumeration value marks the end of the enumeration values. */ + public static final int EvtEventMetadataPropertyIdEND = 9; + } + + /** + * Defines the identifiers that identify the query information that you can retrieve. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa820607(v=vs.85).aspx + */ + public static interface EVT_QUERY_PROPERTY_ID { + + /** + * Identifies the property that contains the list of channel or log file names that are specified in the query. + * The variant type for this property is EvtVarTypeString | EVT_VARIANT_TYPE_ARRAY. + */ + public static final int EvtQueryNames = 0; + + /** + * Identifies the property that contains the list of Win32 error codes that correspond directly to the list of + * channel or log file names that the EvtQueryNames property returns. The error codes indicate the success or + * failure of the query for the specific channel or log file. The variant type for this property is + * EvtVarTypeUInt32 | EVT_VARIANT_TYPE_ARRAY. + */ + public static final int EvtQueryStatuses = 1; + + /** This enumeration value marks the end of the enumeration values. */ + public static final int EvtQueryPropertyIdEND = 2; + } + + /** + * Defines the values that determine the query information to retrieve. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385600(v=vs.85).aspx + */ + public static interface EVT_EVENT_PROPERTY_ID { + + /** + * Not supported. The identifier of the query that selected the event. The variant type of this property is + * EvtVarTypeInt32. + */ + public static final int EvtEventQueryIDs = 0; + + /** + * The channel or log file from which the event came. The variant type of this property is EvtVarTypeString. + */ + public static final int EvtEventPath = 1; + + /** + * This enumeration value marks the end of the enumeration values. It can be used to exit a loop when retrieving + * all the properties. + */ + public static final int EvtEventPropertyIdEND = 2; + } + + /** + * Read access control permission that allows information to be read from an event log. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385781(v=vs.85).aspx + */ + public static final int EVT_READ_ACCESS = 0x1; + + /** + * Write access control permission that allows information to be written to an event log. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385781(v=vs.85).aspx + */ + public static final int EVT_WRITE_ACCESS = 0x2; + + /** + * All (read, write, clear, and delete) access control permission. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385781(v=vs.85).aspx + */ + public static final int EVT_ALL_ACCESS = 0x7; + + /** + * Clear access control permission that allows all information to be cleared from an event log. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa385781(v=vs.85).aspx + */ + public static final int EVT_CLEAR_ACCESS = 0x4; + + public class EVT_HANDLE extends HANDLE { + + public EVT_HANDLE() { + } + + public EVT_HANDLE(Pointer p) { + super(p); + } + + } +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,18 +1,28 @@ /* 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * You can freely decide which license you want to apply to + * the project. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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 java.util.Arrays; import java.util.List; import com.sun.jna.NativeLong; @@ -21,90 +31,99 @@ import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.platform.win32.WinDef.HBITMAP; import com.sun.jna.platform.win32.WinDef.RECT; -import com.sun.jna.win32.StdCallLibrary; /** - * Ported from WinGDI.h. + * Ported from WinGDI.h. * Microsoft Windows SDK 6.0A. * @author dblock[at]dblock.org * @author Andreas "PAX" Lück, onkelpax-git[at]yahoo.de */ -public interface WinGDI extends StdCallLibrary { - public int RDH_RECTANGLES = 1; +public interface WinGDI { + int RDH_RECTANGLES = 1; - public class RGNDATAHEADER extends Structure { + class RGNDATAHEADER extends Structure { + public static final List FIELDS = createFieldsOrder("dwSize", "iType", "nCount", "nRgnSize", "rcBound"); public int dwSize = size(); public int iType = RDH_RECTANGLES; // required public int nCount; public int nRgnSize; public RECT rcBound; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "dwSize", "iType", "nCount", "nRgnSize", "rcBound" }); + + @Override + protected List getFieldOrder() { + return FIELDS; } } - - public class RGNDATA extends Structure { + + class RGNDATA extends Structure { + public static final List FIELDS = createFieldsOrder("rdh", "Buffer" ); public RGNDATAHEADER rdh; public byte[] Buffer; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "rdh", "Buffer" }); - } - - public RGNDATA() { - this(1); + public RGNDATA() { + this(1); } public RGNDATA(int bufferSize) { Buffer = new byte[bufferSize]; allocateMemory(); } + + @Override + protected List getFieldOrder() { + return FIELDS; + } } - public int RGN_AND = 1; - public int RGN_OR = 2; - public int RGN_XOR = 3; - public int RGN_DIFF = 4; - public int RGN_COPY = 5; - - public int ERROR = 0; - public int NULLREGION = 1; - public int SIMPLEREGION = 2; - public int COMPLEXREGION = 3; - - public int ALTERNATE = 1; - public int WINDING = 2; - - public int BI_RGB = 0; - public int BI_RLE8 = 1; - public int BI_RLE4 = 2; - public int BI_BITFIELDS = 3; - public int BI_JPEG = 4; - public int BI_PNG = 5; - - public final int PFD_TYPE_RGBA = 0; - public final int PFD_TYPE_COLORINDEX = 1; - - public final int PFD_MAIN_PLANE = 0; - public final int PFD_OVERLAY_PLANE = 1; - public final int PFD_UNDERLAY_PLANE = (-1); - - public final int PFD_DOUBLEBUFFER = 0x00000001; - public final int PFD_STEREO = 0x00000002; - public final int PFD_DRAW_TO_WINDOW = 0x00000004; - public final int PFD_DRAW_TO_BITMAP = 0x00000008; - public final int PFD_SUPPORT_GDI = 0x00000010; - public final int PFD_SUPPORT_OPENGL = 0x00000020; - public final int PFD_GENERIC_FORMAT = 0x00000040; - public final int PFD_NEED_PALETTE = 0x00000080; - public final int PFD_NEED_SYSTEM_PALETTE = 0x00000100; - public final int PFD_SWAP_EXCHANGE = 0x00000200; - public final int PFD_SWAP_COPY = 0x00000400; - public final int PFD_SWAP_LAYER_BUFFERS = 0x00000800; - public final int PFD_GENERIC_ACCELERATED = 0x00001000; - public final int PFD_SUPPORT_DIRECTDRAW = 0x00002000; + HANDLE HGDI_ERROR = new HANDLE(Pointer.createConstant(0xFFFFFFFF)); + + int RGN_AND = 1; + int RGN_OR = 2; + int RGN_XOR = 3; + int RGN_DIFF = 4; + int RGN_COPY = 5; + + int ERROR = 0; + int NULLREGION = 1; + int SIMPLEREGION = 2; + int COMPLEXREGION = 3; + + int ALTERNATE = 1; + int WINDING = 2; + + int BI_RGB = 0; + int BI_RLE8 = 1; + int BI_RLE4 = 2; + int BI_BITFIELDS = 3; + int BI_JPEG = 4; + int BI_PNG = 5; + + int PFD_TYPE_RGBA = 0; + int PFD_TYPE_COLORINDEX = 1; + + int PFD_MAIN_PLANE = 0; + int PFD_OVERLAY_PLANE = 1; + int PFD_UNDERLAY_PLANE = (-1); + + int PFD_DOUBLEBUFFER = 0x00000001; + int PFD_STEREO = 0x00000002; + int PFD_DRAW_TO_WINDOW = 0x00000004; + int PFD_DRAW_TO_BITMAP = 0x00000008; + int PFD_SUPPORT_GDI = 0x00000010; + int PFD_SUPPORT_OPENGL = 0x00000020; + int PFD_GENERIC_FORMAT = 0x00000040; + int PFD_NEED_PALETTE = 0x00000080; + int PFD_NEED_SYSTEM_PALETTE = 0x00000100; + int PFD_SWAP_EXCHANGE = 0x00000200; + int PFD_SWAP_COPY = 0x00000400; + int PFD_SWAP_LAYER_BUFFERS = 0x00000800; + int PFD_GENERIC_ACCELERATED = 0x00001000; + int PFD_SUPPORT_DIRECTDRAW = 0x00002000; + + class BITMAPINFOHEADER extends Structure { + public static final List FIELDS = createFieldsOrder("biSize", + "biWidth", "biHeight", "biPlanes", "biBitCount", "biCompression", + "biSizeImage", "biXPelsPerMeter", "biYPelsPerMeter", "biClrUsed", "biClrImportant"); - public class BITMAPINFOHEADER extends Structure { public int biSize = size(); public int biWidth; public int biHeight; @@ -116,46 +135,60 @@ public int biYPelsPerMeter; public int biClrUsed; public int biClrImportant; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "biSize", "biWidth", "biHeight", "biPlanes", "biBitCount", "biCompression", "biSizeImage", "biXPelsPerMeter", "biYPelsPerMeter", "biClrUsed", "biClrImportant" }); + + @Override + protected List getFieldOrder() { + return FIELDS; } } - - public class RGBQUAD extends Structure { + + class RGBQUAD extends Structure { + public static final List FIELDS = createFieldsOrder("rgbBlue", "rgbGreen", "rgbRed", "rgbReserved"); + public byte rgbBlue; public byte rgbGreen; public byte rgbRed; public byte rgbReserved = 0; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "rgbBlue", "rgbGreen", "rgbRed", "rgbReserved" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } - - public class BITMAPINFO extends Structure { + + class BITMAPINFO extends Structure { + public static final List FIELDS = createFieldsOrder("bmiHeader", "bmiColors"); + public BITMAPINFOHEADER bmiHeader = new BITMAPINFOHEADER(); public RGBQUAD[] bmiColors = new RGBQUAD[1]; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "bmiHeader", "bmiColors" }); + public BITMAPINFO() { + this(1); } - public BITMAPINFO() { this(1); } public BITMAPINFO(int size) { bmiColors = new RGBQUAD[size]; } + @Override + protected List getFieldOrder() { + return FIELDS; + } } - - public class ICONINFO extends Structure { + + class ICONINFO extends Structure { + public static final List FIELDS = createFieldsOrder("fIcon", "xHotspot", "yHotspot", "hbmMask", "hbmColor"); + public boolean fIcon; public int xHotspot; public int yHotspot; public HBITMAP hbmMask; public HBITMAP hbmColor; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "fIcon", "xHotspot", - "yHotspot", "hbmMask", "hbmColor" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } - - public class BITMAP extends Structure { + + class BITMAP extends Structure { + public static final List FIELDS = createFieldsOrder("bmType", "bmWidth", "bmHeight", + "bmWidthBytes", "bmPlanes", "bmBitsPixel", "bmBits"); public NativeLong bmType; public NativeLong bmWidth; public NativeLong bmHeight; @@ -163,32 +196,40 @@ public short bmPlanes; public short bmBitsPixel; public Pointer bmBits; - protected List getFieldOrder() { - return Arrays.asList("bmType", "bmWidth", "bmHeight", - "bmWidthBytes", "bmPlanes", "bmBitsPixel", "bmBits"); + @Override + protected List getFieldOrder() { + return FIELDS; } } - - public class DIBSECTION extends Structure { + + class DIBSECTION extends Structure { + public static final List FIELDS = createFieldsOrder("dsBm", "dsBmih", "dsBitfields", "dshSection", "dsOffset"); + public BITMAP dsBm; public BITMAPINFOHEADER dsBmih; public int[] dsBitfields = new int[3]; public HANDLE dshSection; - public int dsOffset; - protected List getFieldOrder() { - return Arrays.asList("dsBm", "dsBmih", "dsBitfields", "dshSection", "dsOffset"); + public int dsOffset; + + @Override + protected List getFieldOrder() { + return FIELDS; } } - public int DIB_RGB_COLORS = 0; - public int DIB_PAL_COLORS = 1; + int DIB_RGB_COLORS = 0; + int DIB_PAL_COLORS = 1; /** * The PIXELFORMATDESCRIPTOR structure describes the pixel format of a drawing surface. */ - public static class PIXELFORMATDESCRIPTOR extends Structure { + class PIXELFORMATDESCRIPTOR extends Structure { + public static final List FIELDS = createFieldsOrder("nSize", "nVersion", "dwFlags", "iPixelType", + "cColorBits", "cRedBits", "cRedShift", "cGreenBits", "cGreenShift", "cBlueBits", "cBlueShift", "cAlphaBits", "cAlphaShift", + "cAccumBits", "cAccumRedBits", "cAccumGreenBits", "cAccumBlueBits", "cAccumAlphaBits", + "cDepthBits", "cStencilBits", "cAuxBuffers", "iLayerType", "bReserved", "dwLayerMask", "dwVisibleMask", "dwDamageMask"); + public PIXELFORMATDESCRIPTOR() { - super(); nSize = (short) size(); } @@ -305,13 +346,9 @@ */ public int dwDamageMask; - @SuppressWarnings("rawtypes") @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "nSize", "nVersion", "dwFlags", "iPixelType", - "cColorBits", "cRedBits", "cRedShift", "cGreenBits", "cGreenShift", "cBlueBits", "cBlueShift", "cAlphaBits", "cAlphaShift", - "cAccumBits", "cAccumRedBits", "cAccumGreenBits", "cAccumBlueBits", "cAccumAlphaBits", - "cDepthBits", "cStencilBits", "cAuxBuffers", "iLayerType", "bReserved", "dwLayerMask", "dwVisibleMask", "dwDamageMask", }); + protected List getFieldOrder() { + return FIELDS; } } } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Wininet.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Wininet.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Wininet.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Wininet.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,382 @@ +/* Copyright (c) 2015 Michael Freeman, 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 java.util.List; + +import com.sun.jna.Native; +import com.sun.jna.Pointer; +import com.sun.jna.Structure; +import com.sun.jna.Union; +import com.sun.jna.platform.win32.WinNT.HANDLE; +import com.sun.jna.ptr.IntByReference; +import com.sun.jna.win32.StdCallLibrary; +import com.sun.jna.win32.W32APIOptions; + +/** + * Functions in WinInet.dll + */ +public interface Wininet extends StdCallLibrary { + /** + * A usable instance of this interface + */ + Wininet INSTANCE = Native.loadLibrary("wininet", Wininet.class, W32APIOptions.DEFAULT_OPTIONS); + + /** + * Normal cache entry; can be deleted to recover space for new entries. + */ + int NORMAL_CACHE_ENTRY = 1; + + /** + * Sticky cache entry that is exempt from scavenging for the amount of time + * specified by dwExemptDelta.
    + * The default value set by CommitUrlCacheEntryA and CommitUrlCacheEntryW is + * one day. + */ + int STICKY_CACHE_ENTRY = 4; + + /** + * Cache entry file that has been edited externally. This cache entry type + * is exempt from scavenging. + */ + int EDITED_CACHE_ENTRY = 8; + + /** + * Not currently implemented. + */ + int TRACK_OFFLINE_CACHE_ENTRY = 16; + + /** + * Not currently implemented. + */ + int TRACK_ONLINE_CACHE_ENTRY = 32; + + /** + * Partial response cache entry. + */ + int SPARSE_CACHE_ENTRY = 65536; + + /** + * Cookie cache entry. + */ + int COOKIE_CACHE_ENTRY = 1048576; + + /** + * Visited link cache entry. + */ + int URLHISTORY_CACHE_ENTRY = 2097152; + + /** + * Closes the specified cache enumeration handle. + * + * @param hFind + * Handle returned by a previous call to the + * FindFirstUrlCacheEntry function. + * @return Returns TRUE if successful, or FALSE otherwise. To get extended + * error information, call GetLastError. + */ + boolean FindCloseUrlCache(HANDLE hFind); + + /** + * @param lpszUrlName + * String that contains the name of the source that corresponds + * to the cache entry. + * @return Returns TRUE if successful, or FALSE otherwise.
    + * To get extended error information, call GetLastError.
    + * Possible error values include the following.
    + *
      + *
    • ERROR_ACCESS_DENIED:The file is locked or in use. The + * entry is marked and deleted when the file is unlocked.
    • + *
    • ERROR_FILE_NOT_FOUND:The file is not in the cache. + *
    • + *
    + */ + boolean DeleteUrlCacheEntry(String lpszUrlName); + + /** + * Begins the enumeration of the Internet cache. + * + * @param lpszUrlSearchPattern + * A pointer to a string that contains the source name pattern to + * search for.
    + * This parameter can only be set to "cookie:", "visited:", or + * NULL.
    + * Set this parameter to "cookie:" to enumerate the cookies or + * "visited:" to enumerate the URL History entries in the cache. + *
    + * If this parameter is NULL, FindFirstUrlCacheEntry returns all + * content entries in the cache. + * @param lpFirstCacheEntryInfo + * Pointer to an INTERNET_CACHE_ENTRY_INFO structure. + * @param lpcbCacheEntryInfo + * Pointer to a variable that specifies the size of the + * lpFirstCacheEntryInfo buffer, in bytes.
    + * When the function returns, the variable contains the number of + * bytes copied to the buffer, or the required size needed to + * retrieve the cache entry, in bytes. + * @return Returns a handle that the application can use in the + * FindNextUrlCacheEntry function to retrieve subsequent entries in + * the cache.
    + * If the function fails, the return value is NULL. To get extended + * error information, call GetLastError.
    + * ERROR_INSUFFICIENT_BUFFER indicates that the size of + * lpFirstCacheEntryInfo as specified by + * lpdwFirstCacheEntryInfoBufferSize is not sufficient to contain + * all the information.
    + * The value returned in lpdwFirstCacheEntryInfoBufferSize indicates + * the buffer size necessary to contain all the information. + */ + HANDLE FindFirstUrlCacheEntry(String lpszUrlSearchPattern, INTERNET_CACHE_ENTRY_INFO lpFirstCacheEntryInfo, + IntByReference lpcbCacheEntryInfo); + + /** + * @param hEnumHandle + * Handle to the enumeration obtained from a previous call to + * FindFirstUrlCacheEntry. + * @param lpNextCacheEntryInfo + * Pointer to an INTERNET_CACHE_ENTRY_INFO structure that + * receives information about the cache entry. + * @param lpcbCacheEntryInfo + * Pointer to a variable that specifies the size of the + * lpNextCacheEntryInfo buffer, in bytes.
    + * When the function returns, the variable contains the number of + * bytes copied to the buffer, or the size of the buffer required + * to retrieve the cache entry, in bytes. + * @return Returns TRUE if successful, or FALSE otherwise.
    + * To get extended error information, call GetLastError.
    + * Possible error values include the following.
    + *
      + *
    • ERROR_INSUFFICIENT_BUFFER:The size of + * lpNextCacheEntryInfo as specified by + * lpdwNextCacheEntryInfoBufferSize is not sufficient to contain all + * the information.
      + * The value returned in lpdwNextCacheEntryInfoBufferSize indicates + * the buffer size necessary to contain all the information.
    • + *
    • ERROR_NO_MORE_ITEMS:The enumeration completed.
    • + *
    + */ + boolean FindNextUrlCacheEntry(HANDLE hEnumHandle, INTERNET_CACHE_ENTRY_INFO lpNextCacheEntryInfo, + IntByReference lpcbCacheEntryInfo); + + /** + * Contains information about an entry in the Internet cache. + * + *
    +     * 
    +     * typedef struct _INTERNET_CACHE_ENTRY_INFO {
    +     *   DWORD    dwStructSize;
    +     *   LPTSTR   lpszSourceUrlName;
    +     *   LPTSTR   lpszLocalFileName;
    +     *   DWORD    CacheEntryType;
    +     *   DWORD    dwUseCount;
    +     *   DWORD    dwHitRate;
    +     *   DWORD    dwSizeLow;
    +     *   DWORD    dwSizeHigh;
    +     *   FILETIME LastModifiedTime;
    +     *   FILETIME ExpireTime;
    +     *   FILETIME LastAccessTime;
    +     *   FILETIME LastSyncTime;
    +     *   LPTSTR   lpHeaderInfo;
    +     *   DWORD    dwHeaderInfoSize;
    +     *   LPTSTR   lpszFileExtension;
    +     *   union {
    +     *     DWORD dwReserved;
    +     *     DWORD dwExemptDelta;
    +     *   };
    +     * } INTERNET_CACHE_ENTRY_INFO, *LPINTERNET_CACHE_ENTRY_INFO;
    +     *
    +     *     
    +     * 
    + * + * @see MSDN + */ + static class INTERNET_CACHE_ENTRY_INFO extends Structure { + public static final List FIELDS = createFieldsOrder( + "dwStructSize", "lpszSourceUrlName", "lpszLocalFileName", + "CacheEntryType", "dwUseCount", "dwHitRate", "dwSizeLow", "dwSizeHigh", "LastModifiedTime", + "ExpireTime", "LastAccessTime", "LastSyncTime", "lpHeaderInfo", "dwHeaderInfoSize", + "lpszFileExtension", "u", "additional"); + + /** + * Size of this structure, in bytes. This value can be used to help + * determine the version of the cache system. + */ + public int dwStructSize; + + /** + * Pointer to a null-terminated string that contains the URL name. The + * string occupies the memory area at the end of this structure. + */ + public Pointer lpszSourceUrlName; + + /** + * Pointer to a null-terminated string that contains the local file + * name. The string occupies the memory area at the end of this + * structure. + */ + public Pointer lpszLocalFileName; + + /** + * A bitmask indicating the type of cache entry and its properties.
    + * The cache entry types include: history entries + * (URLHISTORY_CACHE_ENTRY), cookie entries (COOKIE_CACHE_ENTRY), and + * normal cached content (NORMAL_CACHE_ENTRY).
    + *
    + * This member can be zero or more of the following property flags, and + * cache type flags listed below. + *
      + *
    • EDITED_CACHE_ENTRY: Cache entry file that has been edited + * externally. This cache entry type is exempt from scavenging.
    • + *
    • SPARSE_CACHE_ENTRY: Partial response cache entry.
    • + *
    • STICKY_CACHE_ENTRY: Sticky cache entry that is exempt from + * scavenging for the amount of time specified by dwExemptDelta.
      + * The default value set by CommitUrlCacheEntryA and + * CommitUrlCacheEntryW is one day.
    • + *
    • TRACK_OFFLINE_CACHE_ENTRY: Not currently implemented.
    • + *
    • TRACK_ONLINE_CACHE_ENTRY: Not currently implemented.
    • + *
    + *
    + * The following list contains the cache type flags. + *
      + *
    • COOKIE_CACHE_ENTRY: Cookie cache entry.
    • + *
    • NORMAL_CACHE_ENTRY: Normal cache entry; can be deleted to + * recover space for new entries.
    • + *
    • URLHISTORY_CACHE_ENTRY: Visited link cache entry.
    • + *
    + */ + public int CacheEntryType; + + /** + * Current number of WinInet callers using the cache entry. + */ + public int dwUseCount; + + /** + * Number of times the cache entry was retrieved. + */ + public int dwHitRate; + + /** + * Low-order portion of the file size, in bytes. + */ + public int dwSizeLow; + + /** + * High-order portion of the file size, in bytes. + */ + public int dwSizeHigh; + + /** + * FILETIME structure that contains the last modified time of this URL, + * in Greenwich mean time format. + */ + public Kernel32.FILETIME LastModifiedTime; + + /** + * FILETIME structure that contains the expiration time of this file, in + * Greenwich mean time format. + */ + public Kernel32.FILETIME ExpireTime; + + /** + * FILETIME structure that contains the last accessed time, in Greenwich + * mean time format. + */ + public Kernel32.FILETIME LastAccessTime; + + /** + * FILETIME structure that contains the last time the cache was + * synchronized. + */ + public Kernel32.FILETIME LastSyncTime; + + /** + * Pointer to a buffer that contains the header information. The buffer + * occupies the memory at the end of this structure. + */ + public Pointer lpHeaderInfo; + + /** + * Size of the lpHeaderInfo buffer, in TCHARs. + */ + public int dwHeaderInfoSize; + + /** + * Pointer to a string that contains the file name extension used to + * retrieve the data as a file. The string occupies the memory area at + * the end of this structure. + */ + public Pointer lpszFileExtension; + + /** + * A union of the last two distinct fields in INTERNET_CACHE_ENTRY_INFO + */ + public UNION u; + + /** + * Additional data (the path and URLs mentioned previously, and more) + */ + public byte[] additional; + + public INTERNET_CACHE_ENTRY_INFO(int size) { + additional = new byte[size]; + } + + /** + * A union of the last two distinct fields in INTERNET_CACHE_ENTRY_INFO + * + *
    +         * 
    +         *             union {
    +         *                 DWORD dwReserved;
    +         *                 DWORD dwExemptDelta;
    +         *             };
    +         * 
    + */ + public static class UNION extends Union { + /** + * Reserved. Must be zero. + */ + public int dwReserved; + + /** + * Exemption time from the last accessed time, in seconds. + */ + public int dwExemptDelta; + } + + @Override + protected List getFieldOrder() { + return FIELDS; + } + + @Override + public String toString() { + return (lpszLocalFileName == null ? "" : lpszLocalFileName.getWideString(0) + " => ") + + (lpszSourceUrlName == null ? "null" : lpszSourceUrlName.getWideString(0)); + } + + } + +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/WininetUtil.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/WininetUtil.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/WininetUtil.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/WininetUtil.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,137 @@ +/* Copyright (c) 2015 Michael Freeman, 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 java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import com.sun.jna.Native; +import com.sun.jna.platform.win32.Wininet.INTERNET_CACHE_ENTRY_INFO; +import com.sun.jna.platform.win32.WinNT.HANDLE; +import com.sun.jna.ptr.IntByReference; + +/** + * Reusable functions that use WinInet + */ +public class WininetUtil { + /** + * Helper function for traversing wininet's cache and returning all entries. + *
    + * Some entries are cookies, some entries are history items, and some are + * actual files.
    + * + * @return A map of cache URL => local file (or URL => empty string for + * cookie and history entries) + */ + public static Map getCache() { + List items = new ArrayList(); + + HANDLE cacheHandle = null; + Win32Exception we = null; + int lastError = 0; + + // return + Map cacheItems = new LinkedHashMap(); + + try { + IntByReference size = new IntByReference(); + + // for every entry, we call the API twice: + // once to get the size into the IntByReference + // then again to get the actual item + cacheHandle = Wininet.INSTANCE.FindFirstUrlCacheEntry(null, null, size); + lastError = Native.getLastError(); + + // if there's nothing in the cache, we're done. + if (lastError == WinError.ERROR_NO_MORE_ITEMS) { + return cacheItems; + } else if (lastError != WinError.ERROR_SUCCESS && lastError != WinError.ERROR_INSUFFICIENT_BUFFER) { + throw new Win32Exception(lastError); + } + + INTERNET_CACHE_ENTRY_INFO entry = new INTERNET_CACHE_ENTRY_INFO(size.getValue()); + cacheHandle = Wininet.INSTANCE.FindFirstUrlCacheEntry(null, entry, size); + + if (cacheHandle == null) { + throw new Win32Exception(Native.getLastError()); + } + + items.add(entry); + + while (true) { + size = new IntByReference(); + + // for every entry, we call the API twice: + // once to get the size into the IntByReference + // then again to get the actual item + boolean result = Wininet.INSTANCE.FindNextUrlCacheEntry(cacheHandle, null, size); + + if (!result) { + lastError = Native.getLastError(); + if (lastError == WinError.ERROR_NO_MORE_ITEMS) { + break; + } else if (lastError != WinError.ERROR_SUCCESS && lastError != WinError.ERROR_INSUFFICIENT_BUFFER) { + throw new Win32Exception(lastError); + } + } + + entry = new INTERNET_CACHE_ENTRY_INFO(size.getValue()); + result = Wininet.INSTANCE.FindNextUrlCacheEntry(cacheHandle, entry, size); + + if (!result) { + lastError = Native.getLastError(); + if (lastError == WinError.ERROR_NO_MORE_ITEMS) { + break; + } else if (lastError != WinError.ERROR_SUCCESS && lastError != WinError.ERROR_INSUFFICIENT_BUFFER) { + throw new Win32Exception(lastError); + } + } + items.add(entry); + } + + for (INTERNET_CACHE_ENTRY_INFO item : items) { + cacheItems.put(item.lpszSourceUrlName.getWideString(0), item.lpszLocalFileName == null ? "" : item.lpszLocalFileName.getWideString(0)); + } + + } catch (Win32Exception e) { + we = e; + } finally { + if (cacheHandle != null) { + if (!Wininet.INSTANCE.FindCloseUrlCache(cacheHandle)) { + if (we != null) { + Win32Exception e = new Win32Exception(Native.getLastError()); + e.addSuppressed(we); + we = e; + } + } + } + } + if (we != null) { + throw we; + } + return cacheItems; + } +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Winioctl.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Winioctl.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Winioctl.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Winioctl.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,26 +1,132 @@ -/* This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. +/* 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 java.util.Arrays; import java.util.List; import com.sun.jna.Pointer; import com.sun.jna.Structure; -import com.sun.jna.win32.StdCallLibrary; /** * Interface for the Winioctl.h header file. */ -public interface Winioctl extends StdCallLibrary { +public interface Winioctl { + + // Devices + public int FILE_DEVICE_BEEP = 0x00000001; + public int FILE_DEVICE_CD_ROM = 0x00000002; + public int FILE_DEVICE_CD_ROM_FILE_SYSTEM = 0x00000003; + public int FILE_DEVICE_CONTROLLER = 0x00000004; + public int FILE_DEVICE_DATALINK = 0x00000005; + public int FILE_DEVICE_DFS = 0x00000006; + public int FILE_DEVICE_DISK = 0x00000007; + public int FILE_DEVICE_DISK_FILE_SYSTEM = 0x00000008; + public int FILE_DEVICE_FILE_SYSTEM = 0x00000009; + public int FILE_DEVICE_INPORT_PORT = 0x0000000a; + public int FILE_DEVICE_KEYBOARD = 0x0000000b; + public int FILE_DEVICE_MAILSLOT = 0x0000000c; + public int FILE_DEVICE_MIDI_IN = 0x0000000d; + public int FILE_DEVICE_MIDI_OUT = 0x0000000e; + public int FILE_DEVICE_MOUSE = 0x0000000f; + public int FILE_DEVICE_MULTI_UNC_PROVIDER = 0x00000010; + public int FILE_DEVICE_NAMED_PIPE = 0x00000011; + public int FILE_DEVICE_NETWORK = 0x00000012; + public int FILE_DEVICE_NETWORK_BROWSER = 0x00000013; + public int FILE_DEVICE_NETWORK_FILE_SYSTEM = 0x00000014; + public int FILE_DEVICE_NULL = 0x00000015; + public int FILE_DEVICE_PARALLEL_PORT = 0x00000016; + public int FILE_DEVICE_PHYSICAL_NETCARD = 0x00000017; + public int FILE_DEVICE_PRINTER = 0x00000018; + public int FILE_DEVICE_SCANNER = 0x00000019; + public int FILE_DEVICE_SERIAL_MOUSE_PORT = 0x0000001a; + public int FILE_DEVICE_SERIAL_PORT = 0x0000001b; + public int FILE_DEVICE_SCREEN = 0x0000001c; + public int FILE_DEVICE_SOUND = 0x0000001d; + public int FILE_DEVICE_STREAMS = 0x0000001e; + public int FILE_DEVICE_TAPE = 0x0000001f; + public int FILE_DEVICE_TAPE_FILE_SYSTEM = 0x00000020; + public int FILE_DEVICE_TRANSPORT = 0x00000021; + public int FILE_DEVICE_UNKNOWN = 0x00000022; + public int FILE_DEVICE_VIDEO = 0x00000023; + public int FILE_DEVICE_VIRTUAL_DISK = 0x00000024; + public int FILE_DEVICE_WAVE_IN = 0x00000025; + public int FILE_DEVICE_WAVE_OUT = 0x00000026; + public int FILE_DEVICE_8042_PORT = 0x00000027; + public int FILE_DEVICE_NETWORK_REDIRECTOR = 0x00000028; + public int FILE_DEVICE_BATTERY = 0x00000029; + public int FILE_DEVICE_BUS_EXTENDER = 0x0000002a; + public int FILE_DEVICE_MODEM = 0x0000002b; + public int FILE_DEVICE_VDM = 0x0000002c; + public int FILE_DEVICE_MASS_STORAGE = 0x0000002d; + public int FILE_DEVICE_SMB = 0x0000002e; + public int FILE_DEVICE_KS = 0x0000002f; + public int FILE_DEVICE_CHANGER = 0x00000030; + public int FILE_DEVICE_SMARTCARD = 0x00000031; + public int FILE_DEVICE_ACPI = 0x00000032; + public int FILE_DEVICE_DVD = 0x00000033; + public int FILE_DEVICE_FULLSCREEN_VIDEO = 0x00000034; + public int FILE_DEVICE_DFS_FILE_SYSTEM = 0x00000035; + public int FILE_DEVICE_DFS_VOLUME = 0x00000036; + public int FILE_DEVICE_SERENUM = 0x00000037; + public int FILE_DEVICE_TERMSRV = 0x00000038; + public int FILE_DEVICE_KSEC = 0x00000039; + public int FILE_DEVICE_FIPS = 0x0000003A; + public int FILE_DEVICE_INFINIBAND = 0x0000003B; + public int FILE_DEVICE_VMBUS = 0x0000003E; + public int FILE_DEVICE_CRYPT_PROVIDER = 0x0000003F; + public int FILE_DEVICE_WPD = 0x00000040; + public int FILE_DEVICE_BLUETOOTH = 0x00000041; + public int FILE_DEVICE_MT_COMPOSITE = 0x00000042; + public int FILE_DEVICE_MT_TRANSPORT = 0x00000043; + public int FILE_DEVICE_BIOMETRIC = 0x00000044; + public int FILE_DEVICE_PMI = 0x00000045; + public int FILE_DEVICE_EHSTOR = 0x00000046; + public int FILE_DEVICE_DEVAPI = 0x00000047; + public int FILE_DEVICE_GPIO = 0x00000048; + public int FILE_DEVICE_USBEX = 0x00000049; + public int FILE_DEVICE_CONSOLE = 0x00000050; + public int FILE_DEVICE_NFP = 0x00000051; + public int FILE_DEVICE_SYSENV = 0x00000052; + public int FILE_DEVICE_VIRTUAL_BLOCK = 0x00000053; + public int FILE_DEVICE_POINT_OF_SERVICE = 0x00000054; + + // Functions + public int FSCTL_GET_COMPRESSION = 15; + public int FSCTL_SET_COMPRESSION = 16; + public int FSCTL_SET_REPARSE_POINT = 41; + public int FSCTL_GET_REPARSE_POINT = 42; + public int FSCTL_DELETE_REPARSE_POINT = 43; + + // Methods + public int METHOD_BUFFERED = 0; + public int METHOD_IN_DIRECT = 1; + public int METHOD_OUT_DIRECT = 2; + public int METHOD_NEITHER = 3; + + // Access + public int FILE_ANY_ACCESS = 0; + public int FILE_SPECIAL_ACCESS = FILE_ANY_ACCESS; + public int FILE_READ_ACCESS = 0x0001; // file & pipe + public int FILE_WRITE_ACCESS = 0x0002; // file & pipe /** * Retrieves the device type, device number, and, for a partitionable device, the partition number of a device. @@ -42,13 +148,7 @@ } } - public STORAGE_DEVICE_NUMBER() { - } - - public STORAGE_DEVICE_NUMBER(Pointer memory) { - super(memory); - read(); - } + public static final List FIELDS = createFieldsOrder("DeviceType", "DeviceNumber", "PartitionNumber"); /** * The type of device. Values from 0 through 32,767 are reserved for use by Microsoft. Values from 32,768 @@ -65,9 +165,19 @@ * The partition number of the device, if the device can be partitioned. Otherwise, this member is -1. */ public int PartitionNumber; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "DeviceType", "DeviceNumber", "PartitionNumber" }); + + public STORAGE_DEVICE_NUMBER() { + super(); + } + + public STORAGE_DEVICE_NUMBER(Pointer memory) { + super(memory); + read(); + } + + @Override + protected List getFieldOrder() { + return FIELDS; } } } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/WinioctlUtil.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/WinioctlUtil.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/WinioctlUtil.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/WinioctlUtil.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,75 @@ +/* Copyright (c) 2016 Adam Marcionek, 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; + +/** + * Winioctl Utility API. Use WinioctlFunction to construct the full control codes for the + * FSCTL_* functions defined in Winioctl.h + * + * @author amarcionek[at]gmail.com + */ +public abstract class WinioctlUtil { + + /** + * Simulates the macro CTL_CODE from Winioctl.h + * @param DeviceType the device type + * @param Function the function + * @param Method the method + * @param Access the access + * @return int with the resulting control code + */ + public static int CTL_CODE(int DeviceType, int Function, int Method, int Access) { + return ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method); + } + + public static final int FSCTL_GET_COMPRESSION = CTL_CODE( + Winioctl.FILE_DEVICE_FILE_SYSTEM, + Winioctl.FSCTL_GET_COMPRESSION, + Winioctl.METHOD_BUFFERED, + Winioctl.FILE_ANY_ACCESS); + + public static final int FSCTL_SET_COMPRESSION = CTL_CODE( + Winioctl.FILE_DEVICE_FILE_SYSTEM, + Winioctl.FSCTL_SET_COMPRESSION, + Winioctl.METHOD_BUFFERED, + WinNT.FILE_READ_DATA | WinNT.FILE_WRITE_DATA); + + public static final int FSCTL_SET_REPARSE_POINT = CTL_CODE( + Winioctl.FILE_DEVICE_FILE_SYSTEM, + Winioctl.FSCTL_SET_REPARSE_POINT, + Winioctl.METHOD_BUFFERED, + Winioctl.FILE_SPECIAL_ACCESS); + + public static final int FSCTL_GET_REPARSE_POINT = CTL_CODE( + Winioctl.FILE_DEVICE_FILE_SYSTEM, + Winioctl.FSCTL_GET_REPARSE_POINT, + Winioctl.METHOD_BUFFERED, + Winioctl.FILE_ANY_ACCESS); + + public static final int FSCTL_DELETE_REPARSE_POINT = CTL_CODE( + Winioctl.FILE_DEVICE_FILE_SYSTEM, + Winioctl.FSCTL_DELETE_REPARSE_POINT, + Winioctl.METHOD_BUFFERED, + Winioctl.FILE_SPECIAL_ACCESS); +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Winnetwk.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Winnetwk.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Winnetwk.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Winnetwk.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,471 @@ +/* Copyright (c) 2015 Adam Marcionek, 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 java.util.List; + +import com.sun.jna.Pointer; +import com.sun.jna.Structure; +import com.sun.jna.win32.W32APITypeMapper; + +/** + * Ported from AccCtrl.h. Microsoft Windows SDK 7.1 + * + * @author amarcionek[at]gmail.com + */ + +public abstract class Winnetwk { + + /** + * The scope of the enumeration. This member can be one of the following + * values defined in the Winnetwk.h header file. NOTE: This are for the + * dwScope member of NetResource. NOTE: Certain functions allow different + * values of the scope parameter. Consult MSDN for more info. + */ + public class RESOURCESCOPE { + + /** + * Enumerate currently connected resources. The dwUsage member cannot be + * specified. + */ + public static final int RESOURCE_CONNECTED = 1; + + /** + * Enumerate all resources on the network. The dwUsage member is + * specified. + */ + public static final int RESOURCE_GLOBALNET = 2; + + /** + * Enumerate remembered (persistent) connections. The dwUsage member + * cannot be specified. + */ + public static final int RESOURCE_REMEMBERED = 3; + + /** + * NOTE: Definition for this is not defined in Windows Kits nor on MSDN + */ + public static final int RESOURCE_RECENT = 4; + + /** + * Enumerate only resources in the network context of the caller. + * Specify this value for a Network Neighborhood view. The function + * ignores the dwUsage parameter. + */ + public static final int RESOURCE_CONTEXT = 5; + } + + /** + * The type of resource. This member can be one of the following values + * defined in the Winnetwk.h header file. NOTE: This are for the dwType + * member of NetResource + */ + public class RESOURCETYPE { + + /** + * All resources + */ + public static final int RESOURCETYPE_ANY = 0; + + /** + * Disk resources + */ + public static final int RESOURCETYPE_DISK = 1; + + /** + * Print resources + */ + public static final int RESOURCETYPE_PRINT = 2; + + /** + * NOTE: Definition for this is not defined in Windows Kits nor on MSDN + */ + public static final int RESOURCETYPE_RESERVED = 8; + + /** + * The WNetEnumResource function can also return the value + * RESOURCETYPE_UNKNOWN if a resource is neither a disk nor a print + * resource. + */ + public static final int RESOURCETYPE_UNKNOWN = 0xFFFFFFFF; + } + + /** + * The type of resource. This member can be one of the following values + * defined in the Winnetwk.h header file. NOTE: This are for the dwScope + * member of NetResource + */ + public class RESOURCEDISPLAYTYPE { + + /** + * The method used to display the object does not matter. + */ + public static final int RESOURCEDISPLAYTYPE_GENERIC = 0; + + /** + * The object should be displayed as a domain. + */ + public static final int RESOURCEDISPLAYTYPE_DOMAIN = 1; + + /** + * The object should be displayed as a server. + */ + public static final int RESOURCEDISPLAYTYPE_SERVER = 2; + + /** + * The object should be displayed as a share. + */ + public static final int RESOURCEDISPLAYTYPE_SHARE = 3; + + /** + * The object should be displayed as a file. + */ + public static final int RESOURCEDISPLAYTYPE_FILE = 4; + + // TODO: Add the others + } + + /** + * A set of bit flags describing how the resource can be used. Note that + * this member can be specified only if the dwScope member is equal to + * RESOURCE_GLOBALNET. This member can be one of the following values + * defined in the Winnetwk.h header file. NOTE: This are for the dwUsage + * member of NetResource + */ + public class RESOURCEUSAGE { + /** + * The resource is a connectable resource; the name pointed to by the + * lpRemoteName member can be passed to the WNetAddConnection function + * to make a network connection. + */ + public static final int RESOURCEUSAGE_CONNECTABLE = 0x00000001; + + /** + * The resource is a container resource; the name pointed to by the + * lpRemoteName member can be passed to the WNetOpenEnum function to + * enumerate the resources in the container. + */ + public static final int RESOURCEUSAGE_CONTAINER = 0x00000002; + + /** + * The resource is not a local device. + */ + public static final int RESOURCEUSAGE_NOLOCALDEVICE = 0x00000004; + + /** + * The resource is a sibling. This value is not used by Windows. + */ + public static final int RESOURCEUSAGE_SIBLING = 0x00000008; + + /** + * The resource must be attached. This value specifies that a function + * to enumerate resource this should fail if the caller is not + * authenticated, even if the network permits enumeration without + * authentication. + */ + public static final int RESOURCEUSAGE_ATTACHED = 0x00000010; + + /** + * Setting this value is equivalent to setting + * RESOURCEUSAGE_CONNECTABLE, RESOURCEUSAGE_CONTAINER, and + * RESOURCEUSAGE_ATTACHED. + */ + public static final int RESOURCEUSAGE_ALL = RESOURCEUSAGE_CONNECTABLE | RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_ATTACHED; + } + + /** + * A set of bit flags describing how the resource can be used. Note that + * this member can be specified only if the dwScope member is equal to + * RESOURCE_GLOBALNET. This member can be one of the following values + * defined in the Winnetwk.h header file. NOTE: This are for the dwUsage + * member of NetResource + */ + public class ConnectFlag { + + /** + * This flag instructs the operating system to store the network + * resource connection. If this bit flag is set, the operating system + * automatically attempts to restore the connection when the user logs + * on. The system remembers only successful connections that redirect + * local devices. It does not remember connections that are unsuccessful + * or deviceless connections. (A deviceless connection occurs when + * lpLocalName is NULL or when it points to an empty string.) If this + * bit flag is clear, the operating system does not automatically + * restore the connection at logon. + */ + public static final int CONNECT_UPDATE_PROFILE = 0x00000001; + + /** + * If this flag is set, the operating system may interact with the user + * for authentication purposes. + */ + public static final int CONNECT_INTERACTIVE = 0x00000008; + + /** + * This flag instructs the system not to use any default settings for + * user names or passwords without offering the user the opportunity to + * supply an alternative. This flag is ignored unless + * CONNECT_INTERACTIVE is also set. + */ + public static final int CONNECT_PROMPT = 0x00000010; + + /** + * This flag forces the redirection of a local device when making the + * connection. If the lpLocalName member of NETRESOURCE specifies a + * local device to redirect, this flag has no effect, because the + * operating system still attempts to redirect the specified device. + * When the operating system automatically chooses a local device, the + * dwType member must not be equal to RESOURCETYPE_ANY. If this flag is + * not set, a local device is automatically chosen for redirection only + * if the network requires a local device to be redirected. Windows XP: + * When the system automatically assigns network drive letters, letters + * are assigned beginning with Z:, then Y:, and ending with C:. This + * reduces collision between per-logon drive letters (such as network + * drive letters) and global drive letters (such as disk drives). Note + * that previous releases assigned drive letters beginning with C: and + * ending with Z:. + */ + public static final int CONNECT_REDIRECT = 0x00000080; + + /** + * If this flag is set, the connection was made using a local device + * redirection. If the lpAccessName parameter points to a buffer, the + * local device name is copied to the buffer. + */ + public static final int CONNECT_LOCALDRIVE = 0x00000100; + + /** + * If this flag is set, the operating system prompts the user for + * authentication using the command line instead of a graphical user + * interface (GUI). This flag is ignored unless CONNECT_INTERACTIVE is + * also set. Windows 2000/NT and Windows Me/98/95: This value is not + * supported. + */ + public static final int CONNECT_COMMANDLINE = 0x00000800; + + /** + * If this flag is set, and the operating system prompts for a + * credential, the credential should be saved by the credential manager. + * If the credential manager is disabled for the caller's logon session, + * or if the network provider does not support saving credentials, this + * flag is ignored. This flag is also ignored unless you set the + * CONNECT_COMMANDLINE flag. Windows 2000/NT and Windows Me/98/95: This + * value is not supported. + */ + public static final int CONNECT_CMD_SAVECRED = 0x00001000; + } + + /** + * The NETRESOURCE structure contains information about a network resource. + */ + public static class NETRESOURCE extends Structure { + + public static class ByReference extends NETRESOURCE implements Structure.ByReference { + + public ByReference() { + + } + + public ByReference(Pointer memory) { + super(memory); + } + } + + public static final List FIELDS = createFieldsOrder( + "dwScope", "dwType", "dwDisplayType", "dwUsage", "lpLocalName", "lpRemoteName", "lpComment", "lpProvider"); + + /** + * The scope of the enumeration. This member can be one of the values + * defined in class NetResourceSope. + */ + public int dwScope; + + /** + * The type of resource. This member can be one of first 3 values + * defined in the NetResourceType. + */ + public int dwType; + + /** + * The display options for the network object in a network browsing user + * interface. This member can be one of the values defined in the + * NetResourceDisplayType. + */ + public int dwDisplayType; + + /** + * A set of bit flags describing how the resource can be used. + */ + public int dwUsage; + + /** + * If the dwScope member is equal to RESOURCE_CONNECTED or + * RESOURCE_REMEMBERED, this member is a pointer to a null-terminated + * character string that specifies the name of a local device. This + * member is NULL if the connection does not use a device. + */ + public String lpLocalName; + + /** + * If the entry is a network resource, this member is a pointer to a + * null-terminated character string that specifies the remote network + * name. + * + * If the entry is a current or persistent connection, lpRemoteName + * member points to the network name associated with the name pointed to + * by the lpLocalName member. + * + * The string can be MAX_PATH characters in length, and it must follow + * the network provider's naming conventions + */ + public String lpRemoteName; + + /** + * A pointer to a NULL-terminated string that contains a comment + * supplied by the network provider. + */ + public String lpComment; + + /** + * A pointer to a NULL-terminated string that contains the name of the + * provider that owns the resource. This member can be NULL if the + * provider name is unknown. To retrieve the provider name, you can call + * the WNetGetProviderName function. + */ + public String lpProvider; + + public NETRESOURCE() { + super(W32APITypeMapper.DEFAULT); + } + + public NETRESOURCE(Pointer address) { + super(address, Structure.ALIGN_DEFAULT, W32APITypeMapper.DEFAULT); + read(); + } + + @Override + protected List getFieldOrder() { + return FIELDS; + } + } + + // + // Universal Naming. + // + public static int UNIVERSAL_NAME_INFO_LEVEL = 0x00000001; + public static int REMOTE_NAME_INFO_LEVEL = 0x00000002; + + /** + * The UNIVERSAL_NAME_INFO structure contains a pointer to a Universal + * Naming Convention (UNC) name string for a network resource. + */ + public static class UNIVERSAL_NAME_INFO extends Structure { + + public static class ByReference extends REMOTE_NAME_INFO implements Structure.ByReference { + + public ByReference() { + super(); + } + + public ByReference(Pointer memory) { + super(memory); + } + } + + public static final List FIELDS = createFieldsOrder("lpUniversalName"); + /** + * Pointer to the null-terminated UNC name string that identifies a + * network resource. + */ + public String lpUniversalName; + + public UNIVERSAL_NAME_INFO() { + super(W32APITypeMapper.DEFAULT); + } + + public UNIVERSAL_NAME_INFO(Pointer address) { + super(address, Structure.ALIGN_DEFAULT, W32APITypeMapper.DEFAULT); + read(); + } + + @Override + protected List getFieldOrder() { + return FIELDS; + } + } + + /** + * The REMOTE_NAME_INFO structure contains path and name information for a + * network resource. The structure contains a member that points to a + * Universal Naming Convention (UNC) name string for the resource, and two + * members that point to additional network connection information strings. + */ + public static class REMOTE_NAME_INFO extends Structure { + + public static class ByReference extends REMOTE_NAME_INFO implements Structure.ByReference { + + public ByReference() { + + } + + public ByReference(Pointer memory) { + super(memory); + } + } + + public static final List FIELDS = createFieldsOrder("lpUniversalName", "lpConnectionName", "lpRemainingPath"); + + /** + * Pointer to the null-terminated UNC name string that identifies a + * network resource. + */ + public String lpUniversalName; + + /** + * Pointer to a null-terminated string that is the name of a network + * connection. + */ + public String lpConnectionName; + + /** + * Pointer to a null-terminated name string. + */ + public String lpRemainingPath; + + public REMOTE_NAME_INFO() { + super(W32APITypeMapper.DEFAULT); + } + + public REMOTE_NAME_INFO(Pointer address) { + super(address, Structure.ALIGN_DEFAULT, W32APITypeMapper.DEFAULT); + read(); + } + + @Override + protected List getFieldOrder() { + return FIELDS; + } + } +} diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,31 +1,42 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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 java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.List; import com.sun.jna.FromNativeContext; import com.sun.jna.IntegerType; import com.sun.jna.Memory; +import com.sun.jna.Native; import com.sun.jna.NativeLong; import com.sun.jna.Pointer; import com.sun.jna.PointerType; import com.sun.jna.Structure; import com.sun.jna.Union; import com.sun.jna.ptr.ByReference; +import com.sun.jna.win32.StdCallLibrary.StdCallCallback; /** * This module defines the 32-Bit Windows types and constants that are defined @@ -38,6 +49,15 @@ @SuppressWarnings("serial") public interface WinNT extends WinError, WinDef, WinBase, BaseTSD { + int MINCHAR = 0x80; + int MAXCHAR = 0x7f; + int MINSHORT = 0x8000; + int MAXSHORT = 0x7fff; + int MINLONG = 0x80000000; + int MAXLONG = 0x7fffffff; + int MAXBYTE = 0xff; + int MAXWORD = 0xffff; + int MAXDWORD = 0xffffffff; // // The following are masks for the predefined standard access types // @@ -238,6 +258,7 @@ * (LUID) and its attributes. */ public static class LUID_AND_ATTRIBUTES extends Structure { + public static final List FIELDS = createFieldsOrder("Luid", "Attributes"); /** * Specifies an LUID value. */ @@ -250,18 +271,19 @@ */ public DWORD Attributes; - @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "Luid", "Attributes" }); - } - public LUID_AND_ATTRIBUTES() { + super(); } public LUID_AND_ATTRIBUTES(LUID luid, DWORD attributes) { this.Luid = luid; this.Attributes = attributes; } + + @Override + protected List getFieldOrder() { + return FIELDS; + } } /** @@ -269,20 +291,7 @@ * and its attributes. SIDs are used to uniquely identify users or groups. */ public static class SID_AND_ATTRIBUTES extends Structure { - - @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "Sid", "Attributes" }); - } - - public SID_AND_ATTRIBUTES() { - super(); - } - - public SID_AND_ATTRIBUTES(Pointer memory) { - super(memory); - } - + public static final List FIELDS = createFieldsOrder("Sid", "Attributes"); /** * Pointer to a SID structure. */ @@ -293,6 +302,19 @@ * flags. Its meaning depends on the definition and use of the SID. */ public int Attributes; + + public SID_AND_ATTRIBUTES() { + super(); + } + + public SID_AND_ATTRIBUTES(Pointer memory) { + super(memory); + } + + @Override + protected List getFieldOrder() { + return FIELDS; + } } /** @@ -300,11 +322,13 @@ * (SID) that will be applied to newly created objects. */ public static class TOKEN_OWNER extends Structure { - - @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "Owner" }); - } + public static final List FIELDS = createFieldsOrder("Owner"); + /** + * Pointer to a SID structure representing a user who will become the + * owner of any objects created by a process using this access token. + * The SID must be one of the user or group SIDs already in the token. + */ + public PSID.ByReference Owner; // PSID public TOKEN_OWNER() { super(); @@ -319,21 +343,16 @@ read(); } - /** - * Pointer to a SID structure representing a user who will become the - * owner of any objects created by a process using this access token. - * The SID must be one of the user or group SIDs already in the token. - */ - public PSID.ByReference Owner; // PSID + @Override + protected List getFieldOrder() { + return FIELDS; + } } public static class PSID extends Structure { public static class ByReference extends PSID implements Structure.ByReference { } - - @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "sid" }); - } + public static final List FIELDS = createFieldsOrder("sid"); + public Pointer sid; public PSID() { super(); @@ -363,7 +382,10 @@ return Advapi32Util.convertSidToStringSid(this); } - public Pointer sid; + @Override + protected List getFieldOrder() { + return FIELDS; + } } public static class PSIDByReference extends ByReference { @@ -396,11 +418,13 @@ * token. */ public static class TOKEN_USER extends Structure { - - @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "User" }); - } + public static final List FIELDS = createFieldsOrder("User"); + /** + * Specifies a SID_AND_ATTRIBUTES structure representing the user + * associated with the access token. There are currently no attributes + * defined for user security identifiers (SIDs). + */ + public SID_AND_ATTRIBUTES User; public TOKEN_USER() { super(); @@ -415,12 +439,10 @@ super(new Memory(size)); } - /** - * Specifies a SID_AND_ATTRIBUTES structure representing the user - * associated with the access token. There are currently no attributes - * defined for user security identifiers (SIDs). - */ - public SID_AND_ATTRIBUTES User; + @Override + protected List getFieldOrder() { + return FIELDS; + } } /** @@ -428,11 +450,12 @@ * identifiers (SIDs) in an access token. */ public static class TOKEN_GROUPS extends Structure { - - @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "GroupCount", "Group0" }); - } + public static final List FIELDS = createFieldsOrder("GroupCount", "Group0"); + /** + * Specifies the number of groups in the access token. + */ + public int GroupCount; + public SID_AND_ATTRIBUTES Group0; public TOKEN_GROUPS() { super(); @@ -448,12 +471,6 @@ } /** - * Specifies the number of groups in the access token. - */ - public int GroupCount; - public SID_AND_ATTRIBUTES Group0; - - /** * Specifies an array of SID_AND_ATTRIBUTES structures that contain a * set of SIDs and corresponding attributes. * @return attributes @@ -461,6 +478,10 @@ public SID_AND_ATTRIBUTES[] getGroups() { return (SID_AND_ATTRIBUTES[]) Group0.toArray(GroupCount); } + @Override + protected List getFieldOrder() { + return FIELDS; + } } /** @@ -468,15 +489,11 @@ * It is also used to indicate which, if any, privileges are held by a user or group requesting access to an object. */ public static class PRIVILEGE_SET extends Structure { + public static final List FIELDS = createFieldsOrder("PrivilegeCount", "Control", "Privileges"); public DWORD PrivilegeCount; public DWORD Control; public LUID_AND_ATTRIBUTES Privileges[]; - @Override - protected List getFieldOrder() { - return Arrays.asList("PrivilegeCount", "Control", "Privileges"); - } - public PRIVILEGE_SET() { this(0); } @@ -491,7 +508,7 @@ } } - /** Initialize a TOKEN_PRIVILEGES instance from initialized memory. + /** Initialize a TOKEN_PRIVILEGES instance from initialized memory. * @param p base address */ public PRIVILEGE_SET(Pointer p) { @@ -503,6 +520,11 @@ } read(); } + + @Override + protected List getFieldOrder() { + return FIELDS; + } } /** @@ -510,6 +532,7 @@ * privileges for an access token. */ public static class TOKEN_PRIVILEGES extends Structure { + public static final List FIELDS = createFieldsOrder("PrivilegeCount", "Privileges"); /** * This must be set to the number of entries in the Privileges array. */ @@ -521,11 +544,6 @@ */ public LUID_AND_ATTRIBUTES Privileges[]; - @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "PrivilegeCount", "Privileges" }); - } - /** Creates an empty instance with no privileges. */ public TOKEN_PRIVILEGES() { this(0); @@ -549,6 +567,11 @@ Privileges = new LUID_AND_ATTRIBUTES[count]; read(); } + + @Override + protected List getFieldOrder() { + return FIELDS; + } } /** @@ -665,14 +688,99 @@ // AccessSystemAcl access type // - int ACCESS_SYSTEM_SECURITY = 0x01000000; + int ACCESS_SYSTEM_SECURITY = 0x01000000; - int PAGE_READONLY = 0x02; - int PAGE_READWRITE = 0x04; + /** + * Pages in the region become guard pages.
    + * Any attempt to access a guard page causes the system to raise a + * STATUS_GUARD_PAGE_VIOLATION exception and turn off the guard page status. + *
    + * Guard pages thus act as a one-time access alarm.
    + * For more information, see Creating Guard Pages.
    + * When an access attempt leads the system to turn off guard page status, + * the underlying page protection takes over.
    + * If a guard page exception occurs during a system service, the service + * typically returns a failure status indicator.
    + * This value cannot be used with PAGE_NOACCESS. This flag is not supported + * by the CreateFileMapping function. + * + * @see + * MSDN + */ + int PAGE_GUARD = 0x100; + + /** + * Disables all access to the committed region of pages.
    + * An attempt to read from, write to, or execute the committed region + * results in an access violation.
    + * This flag is not supported by the CreateFileMapping function. + * + * @see MSDN + */ + int PAGE_NOACCESS = 0x01; + + /** + * Enables read-only access to the committed region of pages.
    + * An attempt to write to the committed region results in an access + * violation.
    + * If Data Execution Prevention is enabled, an attempt to execute code in + * the committed region results in an access violation. + * + * @see MSDN + */ + int PAGE_READONLY = 0x02; + + /** + * Enables read-only or read/write access to the committed region of pages.
    + * If Data Execution Prevention is enabled, attempting to execute code in + * the committed region results in an access violation. + * + * @see MSDN + */ + int PAGE_READWRITE = 0x04; + + /** + * Enables read-only or copy-on-write access to a mapped view of a file + * mapping object. An attempt to write to a committed copy-on-write page + * results in a private copy of the page being made for the process. The + * private page is marked as PAGE_READWRITE, and the change is written to + * the new page. If Data Execution Prevention is enabled, attempting to + * execute code in the committed region results in an access violation. + * + * @see MSDN + */ int PAGE_WRITECOPY = 0x08; - int PAGE_EXECUTE = 0x10; - int PAGE_EXECUTE_READ = 0x20; - int PAGE_EXECUTE_READWRITE = 0x40; + + /** + * Enables execute access to the committed region of pages. An attempt to + * write to the committed region results in an access violation. This flag + * is not supported by the CreateFileMapping function. + * + * @see MSDN + */ + int PAGE_EXECUTE = 0x10; + + /** + * Enables execute or read-only access to the committed region of pages. An + * attempt to write to the committed region results in an access violation. + * Windows Server 2003 and Windows XP: This attribute is not supported by + * the CreateFileMapping function until Windows XP with SP2 and Windows + * Server 2003 with SP1. + * + * @see MSDN + */ + int PAGE_EXECUTE_READ = 0x20; + + /** + * Enables execute, read-only, or read/write access to the committed region + * of pages. Windows Server 2003 and Windows XP: This attribute is not + * supported by the CreateFileMapping function until Windows XP with SP2 and + * Windows Server 2003 with SP1. + * + * @see MSDN + */ + int PAGE_EXECUTE_READWRITE = 0x40; int SECTION_QUERY = 0x0001; int SECTION_MAP_WRITE = 0x0002; @@ -739,6 +847,16 @@ int FILE_SUPPORTS_OPEN_BY_FILE_ID = 0x01000000; int FILE_SUPPORTS_USN_JOURNAL = 0x02000000; + // Reparse point tags + int IO_REPARSE_TAG_MOUNT_POINT = 0xA0000003; + int IO_REPARSE_TAG_HSM = 0xC0000004; + int IO_REPARSE_TAG_HSM2 = 0x80000006; + int IO_REPARSE_TAG_SIS = 0x80000007; + int IO_REPARSE_TAG_WIM = 0x80000008; + int IO_REPARSE_TAG_CSV = 0x80000009; + int IO_REPARSE_TAG_DFS = 0x8000000A; + int IO_REPARSE_TAG_SYMLINK = 0xA000000C; + int IO_REPARSE_TAG_DFSR = 0x80000012; // The controllable aspects of the DefineDosDevice function. // see https://msdn.microsoft.com/en-us/library/windows/desktop/aa363904(v=vs.85).aspx @@ -747,6 +865,15 @@ int DDD_EXACT_MATCH_ON_REMOVE = 0x00000004; int DDD_NO_BROADCAST_SYSTEM = 0x00000008; + int COMPRESSION_FORMAT_NONE = 0x0000; + int COMPRESSION_FORMAT_DEFAULT = 0x0001; + int COMPRESSION_FORMAT_LZNT1 = 0x0002; + int COMPRESSION_FORMAT_XPRESS = 0x0003; + int COMPRESSION_FORMAT_XPRESS_HUFF = 0x0004; + int COMPRESSION_ENGINE_STANDARD = 0x0000; + int COMPRESSION_ENGINE_MAXIMUM = 0x0100; + int COMPRESSION_ENGINE_HIBER = 0x0200; + /** * The FILE_NOTIFY_INFORMATION structure describes the changes found by the * ReadDirectoryChangesW function. @@ -756,18 +883,15 @@ * for input. */ public static class FILE_NOTIFY_INFORMATION extends Structure { + public static final List FIELDS = createFieldsOrder("NextEntryOffset", "Action", "FileNameLength", "FileName"); public int NextEntryOffset; public int Action; public int FileNameLength; // filename is not nul-terminated, so we can't use a String/WString public char[] FileName = new char[1]; - @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "NextEntryOffset", "Action", "FileNameLength", "FileName" }); - } - private FILE_NOTIFY_INFORMATION() { + super(); } public FILE_NOTIFY_INFORMATION(int size) { @@ -788,6 +912,11 @@ } @Override + protected List getFieldOrder() { + return FIELDS; + } + + @Override public void read() { // avoid reading filename until we know how long it is FileName = new char[0]; @@ -1039,12 +1168,13 @@ * that generated it until the system is restarted. */ public static class LUID extends Structure { + public static final List FIELDS = createFieldsOrder("LowPart", "HighPart"); public int LowPart; public int HighPart; @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "LowPart", "HighPart" }); + protected List getFieldOrder() { + return FIELDS; } } @@ -1057,6 +1187,7 @@ } public static class LowHigh extends Structure { + public static final List FIELDS = createFieldsOrder("LowPart", "HighPart"); public DWORD LowPart; public DWORD HighPart; @@ -1075,7 +1206,7 @@ @Override protected List getFieldOrder() { - return Arrays.asList("LowPart", "HighPart"); + return FIELDS; } public long longValue() { @@ -1731,6 +1862,9 @@ * operating system. This structure is used with the GetVersionEx function. */ public static class OSVERSIONINFO extends Structure { + public static final List FIELDS = createFieldsOrder( + "dwOSVersionInfoSize", "dwMajorVersion", "dwMinorVersion", "dwBuildNumber", "dwPlatformId", "szCSDVersion"); + /** * Size of this data structure, in bytes. Set this member to * sizeof(OSVERSIONINFO) before calling the GetVersionEx function. @@ -1763,11 +1897,6 @@ */ public char szCSDVersion[]; - @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "dwOSVersionInfoSize", "dwMajorVersion", "dwMinorVersion", "dwBuildNumber", "dwPlatformId", "szCSDVersion" }); - } - public OSVERSIONINFO() { szCSDVersion = new char[128]; dwOSVersionInfoSize = new DWORD(size()); // sizeof(OSVERSIONINFO) @@ -1777,6 +1906,11 @@ super(memory); read(); } + + @Override + protected List getFieldOrder() { + return FIELDS; + } } /** @@ -1786,6 +1920,14 @@ * installed on the system. */ public static class OSVERSIONINFOEX extends Structure { + public static final List FIELDS = createFieldsOrder( + "dwOSVersionInfoSize", + "dwMajorVersion", "dwMinorVersion", "dwBuildNumber", + "dwPlatformId", + "szCSDVersion", + "wServicePackMajor", "wServicePackMinor", + "wSuiteMask", "wProductType", "wReserved"); + /** * The size of this data structure, in bytes. */ @@ -1849,11 +1991,6 @@ */ public byte wReserved; - @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "dwOSVersionInfoSize", "dwMajorVersion", "dwMinorVersion", "dwBuildNumber", "dwPlatformId", "szCSDVersion", "wServicePackMajor", "wServicePackMinor", "wSuiteMask", "wProductType", "wReserved"}); - } - public OSVERSIONINFOEX() { szCSDVersion = new char[128]; dwOSVersionInfoSize = new DWORD(size()); // sizeof(OSVERSIONINFOEX) @@ -1863,6 +2000,62 @@ super(memory); read(); } + + @Override + protected List getFieldOrder() { + return FIELDS; + } + + /** + * @return The major version number of the operating system. + */ + public int getMajor() { + return dwMajorVersion.intValue(); + } + + /** + * @return The minor version number of the operating system. + */ + public int getMinor() { + return dwMinorVersion.intValue(); + } + + /** + * @return The build number of the operating system. + */ + public int getBuildNumber() { + return dwBuildNumber.intValue(); + } + + /** + * @return The operating system platform. This member can be VER_PLATFORM_WIN32_NT. + */ + public int getPlatformId() { + return dwPlatformId.intValue(); + } + + /** + * @return String, such as "Service Pack 3", that indicates the latest + * Service Pack installed on the system.
    + * If no Service Pack has been installed, the string is empty. + */ + public String getServicePack() { + return Native.toString(szCSDVersion); + } + + /** + * @return A bit mask that identifies the product suites available on the system. + */ + public int getSuiteMask() { + return wSuiteMask.intValue(); + } + + /** + * @return Any additional information about the system. + */ + public byte getProductType() { + return wProductType; + } } int VER_EQUAL = 1; @@ -1953,6 +2146,12 @@ * returned by the ReadEventLog function. */ public static class EVENTLOGRECORD extends Structure { + public static final List FIELDS = createFieldsOrder( + "Length", "Reserved", "RecordNumber", "TimeGenerated", "TimeWritten", + "EventID", "EventType", "NumStrings", "EventCategory", "ReservedFlags", + "ClosingRecordNumber", "StringOffset", "UserSidLength", "UserSidOffset", + "DataLength", "DataOffset"); + /** * Size of this event record, in bytes. Note that this value is stored * at both ends of the entry to ease moving forward or backward through @@ -2055,18 +2254,19 @@ */ public DWORD DataOffset; - @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "Length", "Reserved", "RecordNumber", "TimeGenerated", "TimeWritten", "EventID", "EventType", "NumStrings", "EventCategory", "ReservedFlags", "ClosingRecordNumber", "StringOffset", "UserSidLength", "UserSidOffset", "DataLength", "DataOffset"}); - } - public EVENTLOGRECORD() { + super(); } public EVENTLOGRECORD(Pointer p) { super(p); read(); } + + @Override + protected List getFieldOrder() { + return FIELDS; + } } // @@ -2084,6 +2284,25 @@ int SERVICE_INTERACTIVE_PROCESS = 0x00000100; int SERVICE_TYPE_ALL = SERVICE_WIN32 | SERVICE_ADAPTER | SERVICE_DRIVER | SERVICE_INTERACTIVE_PROCESS; + + // + // Start Type + // + + int SERVICE_BOOT_START = 0x00000000; + int SERVICE_SYSTEM_START = 0x00000001; + int SERVICE_AUTO_START = 0x00000002; + int SERVICE_DEMAND_START = 0x00000003; + int SERVICE_DISABLED = 0x00000004; + + // + // Error control type + // + int SERVICE_ERROR_IGNORE = 0x00000000; + int SERVICE_ERROR_NORMAL = 0x00000001; + int SERVICE_ERROR_SEVERE = 0x00000002; + int SERVICE_ERROR_CRITICAL = 0x00000003; + int STATUS_PENDING = 0x00000103; // Privilege Constants @@ -2136,6 +2355,42 @@ */ int PROCESS_DUP_HANDLE = 0x0040; + /** + * All possible access rights for a process object. Windows Server 2003 and + * Windows XP: The size of the PROCESS_ALL_ACCESS flag increased on Windows + * Server 2008 and Windows Vista.
    + * If an application compiled for Windows Server 2008 and Windows Vista is + * run on Windows Server 2003 or Windows XP, the PROCESS_ALL_ACCESS flag is + * too large and the function specifying this flag fails with + * ERROR_ACCESS_DENIED.
    + * To avoid this problem, specify the minimum set of access rights required + * for the operation.
    + * If PROCESS_ALL_ACCESS must be used, set _WIN32_WINNT to the minimum + * operating system targeted by your application (for example, #define + * _WIN32_WINNT _WIN32_WINNT_WINXP).
    + * For more information, see Using the Windows Headers. + * + * @see MSDN + */ + int PROCESS_ALL_ACCESS = WinNT.PROCESS_CREATE_PROCESS + | WinNT.PROCESS_CREATE_THREAD + | WinNT.PROCESS_DUP_HANDLE + | WinNT.PROCESS_QUERY_INFORMATION + | WinNT.PROCESS_QUERY_LIMITED_INFORMATION + | WinNT.PROCESS_SET_INFORMATION + | WinNT.PROCESS_SET_QUOTA + | WinNT.PROCESS_SUSPEND_RESUME + | WinNT.PROCESS_SYNCHRONIZE + | WinNT.PROCESS_TERMINATE + | WinNT.PROCESS_VM_OPERATION + | WinNT.PROCESS_VM_READ + | WinNT.PROCESS_VM_WRITE + | WinNT.DELETE + | WinNT.READ_CONTROL + | WinNT.WRITE_DAC + | WinNT.WRITE_OWNER + | WinNT.SYNCHRONIZE; + /** * Required to retrieve certain information about a process, such as its * token, exit code, and priority class (see @@ -2176,6 +2431,12 @@ */ int PROCESS_TERMINATE = 0x00000001; + /** + * Required for getting process exe path in native system path format + * {@code Kernel32.QueryFullProcessImageName()}. + */ + int PROCESS_NAME_NATIVE = 0x00000001; + /** * Required to perform an operation on the address space of a process (see * {@code Kernel32.VirtualProtectEx()} and @@ -2228,13 +2489,18 @@ int SE_RM_CONTROL_VALID = 0x00004000; int SE_SELF_RELATIVE = 0x00008000; + int SECURITY_DESCRIPTOR_REVISION = 0x00000001; public static class SECURITY_DESCRIPTOR extends Structure { public static class ByReference extends SECURITY_DESCRIPTOR implements Structure.ByReference { } + public static final List FIELDS = createFieldsOrder("data"); + public byte[] data; + public SECURITY_DESCRIPTOR() { + super(); } public SECURITY_DESCRIPTOR(byte[] data) { @@ -2243,27 +2509,59 @@ useMemory(new Memory(data.length)); } + public SECURITY_DESCRIPTOR(int size) { + super(); + useMemory(new Memory(size)); + data = new byte[size]; + } + public SECURITY_DESCRIPTOR(Pointer memory) { super(memory); read(); } - public byte[] data; - @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "data" }); + protected List getFieldOrder() { + return FIELDS; } } + int ACL_REVISION = 2; + int ACL_REVISION_DS = 4; + + // This is the history of ACL revisions. Add a new one whenever + // ACL_REVISION is updated + int ACL_REVISION1 = 1; + int ACL_REVISION2 = 2; + int ACL_REVISION3 = 3; + int ACL_REVISION4 = 4; + int MIN_ACL_REVISION = ACL_REVISION2; + int MAX_ACL_REVISION = ACL_REVISION4; + public static class ACL extends Structure { + public static final List FIELDS = createFieldsOrder("AclRevision", "Sbz1", "AclSize", "AceCount", "Sbz2"); - @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "AclRevision", "Sbz1", "AclSize", "AceCount", "Sbz2" }); - } + /* + * Maximum size chosen based on technet article: + * https://technet.microsoft.com/en-us/library/cc781716.aspx + */ + public static int MAX_ACL_SIZE = 64 * 1024; + + public byte AclRevision; + public byte Sbz1; + public short AclSize; + public short AceCount; + public short Sbz2; + + private ACCESS_ACEStructure[] ACEs; public ACL() { + super(); + } + + public ACL(int size) { + super(); + useMemory(new Memory(size)); } public ACL(Pointer pointer) { @@ -2275,34 +2573,55 @@ Pointer share = pointer.share(offset); // ACE_HEADER.AceType final byte aceType = share.getByte(0); - ACCESS_ACEStructure ace = null; + ACCESS_ACEStructure ace; switch (aceType) { - case ACCESS_ALLOWED_ACE_TYPE: - ace = new ACCESS_ALLOWED_ACE(share); - break; - case ACCESS_DENIED_ACE_TYPE: - ace = new ACCESS_DENIED_ACE(share); - break; - default: - throw new IllegalArgumentException("Unknown ACE type " - + aceType); + case ACCESS_ALLOWED_ACE_TYPE: + ace = new ACCESS_ALLOWED_ACE(share); + break; + case ACCESS_DENIED_ACE_TYPE: + ace = new ACCESS_DENIED_ACE(share); + break; + default: + throw new IllegalArgumentException("Unknown ACE type " + aceType); } ACEs[i] = ace; offset += ace.AceSize; } } - public byte AclRevision; - public byte Sbz1; - public short AclSize; - public short AceCount; - public short Sbz2; - - private ACCESS_ACEStructure[] ACEs; - public ACCESS_ACEStructure[] getACEStructures() { return ACEs; } + + @Override + protected List getFieldOrder() { + return FIELDS; + } + } + + public static class PACLByReference extends ByReference { + public PACLByReference() { + this(null); + } + + public PACLByReference(ACL h) { + super(Pointer.SIZE); + setValue(h); + } + + public void setValue(ACL h) { + getPointer().setPointer(0, h != null ? h.getPointer() : null); + } + + public ACL getValue() { + Pointer p = getPointer().getPointer(0); + if (p == null) { + return null; + } + else { + return new ACL(p); + } + } } public static class SECURITY_DESCRIPTOR_RELATIVE extends Structure { @@ -2310,6 +2629,8 @@ implements Structure.ByReference { } + public static final List FIELDS = createFieldsOrder("Revision", "Sbz1", "Control", "Owner", "Group", "Sacl", "Dacl"); + public byte Revision; public byte Sbz1; public short Control; @@ -2318,17 +2639,13 @@ public int Sacl; public int Dacl; - @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "Revision", "Sbz1", "Control", "Owner", "Group", "Sacl", "Dacl" }); - } - - private ACL DACL; private PSID OWNER; private PSID GROUP; private ACL SACL; + private ACL DACL; public SECURITY_DESCRIPTOR_RELATIVE() { + super(); } public SECURITY_DESCRIPTOR_RELATIVE(byte[] data) { @@ -2337,6 +2654,10 @@ setMembers(); } + public SECURITY_DESCRIPTOR_RELATIVE(int length) { + super(new Memory(length)); + } + public SECURITY_DESCRIPTOR_RELATIVE(Pointer p) { super(p); setMembers(); @@ -2373,23 +2694,37 @@ OWNER = new PSID(getPointer().share(Owner)); } } + + @Override + protected List getFieldOrder() { + return FIELDS; + } } public static abstract class ACEStructure extends Structure { + public static final List FIELDS = createFieldsOrder("AceType", "AceFlags", "AceSize"); + public byte AceType; public byte AceFlags; public short AceSize; PSID psid; - public ACEStructure() { } + public ACEStructure() { + super(); + } + public ACEStructure(Pointer p) { super(p); } - @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "AceType", "AceFlags", "AceSize" }); + public ACEStructure(byte AceType, byte AceFlags, short AceSize, PSID psid) { + super(); + this.AceType = AceType; + this.AceFlags = AceFlags; + this.AceSize = AceSize; + this.psid = psid; + write(); } public String getSidString() { @@ -2399,11 +2734,19 @@ public PSID getSID() { return psid; } + + @Override + protected List getFieldOrder() { + return FIELDS; + } } /* ACE header */ public static class ACE_HEADER extends ACEStructure { - public ACE_HEADER() { } + public ACE_HEADER() { + super(); + } + public ACE_HEADER(Pointer p) { super(p); read(); @@ -2414,47 +2757,100 @@ * ACCESS_ALLOWED_ACE and ACCESS_DENIED_ACE have the same structure layout */ public static abstract class ACCESS_ACEStructure extends ACEStructure { - @Override - protected List getFieldOrder() { - List list = new ArrayList(super.getFieldOrder()); - list.addAll(Arrays.asList(new String[] { "Mask", "SidStart"})); - return list; + public static final List FIELDS = createFieldsOrder(ACEStructure.FIELDS, "Mask", "SidStart"); + + public int Mask; + /** + * First 4 bytes of the SID + * Only used to have a valid field defined - use sid! + */ + public byte[] SidStart = new byte[4]; + + public ACCESS_ACEStructure() { + super(); + } + + public ACCESS_ACEStructure(int Mask, byte AceType, byte AceFlags, PSID psid) { + super(); + this.calculateSize(true); + this.AceType = AceType; + this.AceFlags = AceFlags; + this.AceSize = (short) (super.fieldOffset("SidStart") + psid.getBytes().length); + this.psid = psid; + this.Mask = Mask; + this.SidStart = psid.getPointer().getByteArray(0, SidStart.length); + this.allocateMemory(AceSize); + write(); } - public ACCESS_ACEStructure() { } + public ACCESS_ACEStructure(Pointer p) { super(p); read(); - // AceSize - size of public members of the structure + size of DWORD - // (SidStart) - int sizeOfSID = super.AceSize - size() + 4; - // ACE_HEADER + size of int (Mask) - int offsetOfSID = 4 + 4; - byte[] data = p.getByteArray(offsetOfSID, sizeOfSID); - psid = new PSID(data); } - public int Mask; - /** - * first 4 bytes of the SID + * Write override due to psid not being a managed field */ - public DWORD SidStart; + @Override + public void write() { + super.write(); + int offsetOfSID = super.fieldOffset("SidStart"); + int sizeOfSID = super.AceSize - super.fieldOffset("SidStart"); + if(psid != null) { + // Get bytes from the PSID + byte[] psidWrite = psid.getBytes(); + assert psidWrite.length <= sizeOfSID; + // Write those bytes to native memory + getPointer().write(offsetOfSID, psidWrite, 0, sizeOfSID); + } + } + + @Override + public void read() { + super.read(); + int offsetOfSID = super.fieldOffset("SidStart"); + int sizeOfSID = super.AceSize - super.fieldOffset("SidStart"); + if(sizeOfSID > 0) { + psid = new PSID(getPointer().getByteArray(offsetOfSID, sizeOfSID)); + } else { + psid = new PSID(); + } + } + + @Override + protected List getFieldOrder() { + return FIELDS; + } } /* Access allowed ACE */ public static class ACCESS_ALLOWED_ACE extends ACCESS_ACEStructure { - public ACCESS_ALLOWED_ACE() { } + public ACCESS_ALLOWED_ACE() { + super(); + } + public ACCESS_ALLOWED_ACE(Pointer p) { super(p); } + + public ACCESS_ALLOWED_ACE(int Mask, byte AceFlags, PSID psid) { + super(Mask, ACCESS_ALLOWED_ACE_TYPE, AceFlags, psid); + } } /* Access denied ACE */ public static class ACCESS_DENIED_ACE extends ACCESS_ACEStructure { - public ACCESS_DENIED_ACE() { } + public ACCESS_DENIED_ACE() { + super(); + } + public ACCESS_DENIED_ACE(Pointer p) { super(p); } + + public ACCESS_DENIED_ACE(int Mask, byte AceFlags, PSID psid) { + super(Mask, ACCESS_DENIED_ACE_TYPE, AceFlags, psid); + } } /* ACE types */ @@ -2499,14 +2895,17 @@ public static class ByReference extends GENERIC_MAPPING implements Structure.ByReference { } + public static final List FIELDS = createFieldsOrder( + "genericRead", "genericWrite", "genericExecute", "genericAll"); + public DWORD genericRead; public DWORD genericWrite; public DWORD genericExecute; public DWORD genericAll; @Override - protected List getFieldOrder() { - return Arrays.asList("genericRead", "genericWrite", "genericExecute", "genericAll"); + protected List getFieldOrder() { + return FIELDS; } } @@ -2515,6 +2914,8 @@ * {@link Kernel32#GetLogicalProcessorInformation} function. */ public static class SYSTEM_LOGICAL_PROCESSOR_INFORMATION extends Structure { + public static final List FIELDS = createFieldsOrder("processorMask", "relationship", "payload"); + /** * The processor mask identifying the processors described by this structure. A processor mask is a bit * vector in which each set bit represents an active processor in the relationship. @@ -2539,6 +2940,7 @@ public AnonymousUnionPayload payload; public SYSTEM_LOGICAL_PROCESSOR_INFORMATION() { + super(); } public SYSTEM_LOGICAL_PROCESSOR_INFORMATION(Pointer memory) { @@ -2547,8 +2949,8 @@ } @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "processorMask", "relationship", "payload" }); + protected List getFieldOrder() { + return FIELDS; } public static class AnonymousUnionPayload extends Union { @@ -2582,6 +2984,7 @@ } public static class AnonymousStructProcessorCore extends Structure { + public static final List FIELDS = createFieldsOrder("flags"); /** *

    If the value of this mmeber is {@code 1}, the logical processors identified by the value of the * {@link #processorMask} member share functional units, as in Hyperthreading or SMT. Otherwise, the @@ -2593,12 +2996,13 @@ public BYTE flags; @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "flags" }); + protected List getFieldOrder() { + return FIELDS; } } public static class AnonymousStructNumaNode extends Structure { + public static final List FIELDS = createFieldsOrder("nodeNumber"); /** * Identifies the NUMA node. Valid values are {@code 0} to the highest NUMA node number inclusive. * A non-NUMA multiprocessor system will report that all processors belong to one NUMA node. @@ -2606,8 +3010,8 @@ public DWORD nodeNumber; @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "nodeNumber" }); + protected List getFieldOrder() { + return FIELDS; } } } @@ -2664,6 +3068,7 @@ * Describes the cache attributes. */ public static class CACHE_DESCRIPTOR extends Structure { + public static final List FIELDS = createFieldsOrder("level", "associativity", "lineSize", "size", "type"); /** * The cache level. This member can be 1, 2 or 3, corresponding to L1, L2 or L3 cache, respectively (other * values may be supported in the future.) @@ -2694,8 +3099,8 @@ public int /* PROCESSOR_CACHE_TYPE */ type; @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "level", "associativity", "lineSize", "size", "type" }); + protected List getFieldOrder() { + return FIELDS; } } @@ -2757,6 +3162,8 @@ int MEM_PRIVATE = 0x20000; public static class MEMORY_BASIC_INFORMATION extends Structure { + public static final List FIELDS = createFieldsOrder("baseAddress", "allocationBase", "allocationProtect", + "regionSize", "state", "protect", "type"); /** * A pointer to the base address of the region of pages. @@ -2807,11 +3214,62 @@ public DWORD type; @Override - protected List getFieldOrder() { - return Arrays.asList(new String[]{ - "baseAddress", "allocationBase", "allocationProtect", - "regionSize", "state", "protect", "type" - }); + protected List getFieldOrder() { + return FIELDS; + } + } + + public class SECURITY_QUALITY_OF_SERVICE extends Structure { + + public static final List FIELDS = createFieldsOrder( + "Length", "ImpersonationLevel", "ContextTrackingMode", "EffectiveOnly" + ); + + /** Specifies the size, in bytes, of this structure. + */ + public int Length; + /** + * Specifies the information given to the server about the client, and + * how the server may represent, or impersonate, the client. Security + * impersonation levels govern the degree to which a server process can + * act on behalf of a client process. This member is a + * {@link WinNT.SECURITY_IMPERSONATION_LEVEL} enumeration type value. + */ + public int ImpersonationLevel; + /** + * Specifies whether the server is to be given a snapshot of the + * client's security context (called static tracking), or is to be + * continually updated to track changes to the client's security context + * (called dynamic tracking). The {@link WinNT#SECURITY_STATIC_TRACKING} + * value specifies static tracking, and the + * {@link WinNT#SECURITY_DYNAMIC_TRACKING} value specifies dynamic + * tracking. Not all communications mechanisms support dynamic tracking; + * those that do not will default to static tracking. + */ + public byte ContextTrackingMode; + /** + * Specifies whether the server may enable or disable privileges and + * groups that the client's security context may include. + * + *

    This is a boolean value. See {@link WinNT#BOOLEAN_TRUE} and + * {@link WinNT#BOOLEAN_FALSE}.

    + */ + public byte EffectiveOnly; + + @Override + public void write() { + this.Length = size(); + super.write(); + } + + @Override + protected List getFieldOrder() { + return FIELDS; } } + + byte SECURITY_DYNAMIC_TRACKING = (byte) 1; + byte SECURITY_STATIC_TRACKING = (byte) 0; + byte BOOLEAN_TRUE = (byte) 1; + byte BOOLEAN_FALSE = (byte) 0; } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/WinPerf.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/WinPerf.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/WinPerf.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/WinPerf.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,18 +1,28 @@ /* Copyright (c) 2015 Goldstein Lyor, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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 java.util.Arrays; import java.util.List; import com.sun.jna.Structure; @@ -30,6 +40,13 @@ * @see PERF_DATA_BLOCK */ public class PERF_DATA_BLOCK extends Structure { + public static final List FIELDS = createFieldsOrder( + "Signature", "LittleEndian", "Version", + "Revision", "TotalByteLength", "HeaderLength", + "NumObjectTypes", "DefaultObject", "SystemTime", + "PerfTime", "PerfFreq", "PerfTime100nSec", + "SystemNameLength", "SystemNameOffset"); + public char[] Signature = new char[4]; public int LittleEndian; public int Version; @@ -47,11 +64,7 @@ @Override protected List getFieldOrder() { - return Arrays.asList("Signature", "LittleEndian", "Version", - "Revision", "TotalByteLength", "HeaderLength", - "NumObjectTypes", "DefaultObject", "SystemTime", - "PerfTime", "PerfFreq", "PerfTime100nSec", - "SystemNameLength", "SystemNameOffset"); + return FIELDS; } }; @@ -60,6 +73,10 @@ * @see PERF_INSTANCE_DEFINITION */ public class PERF_INSTANCE_DEFINITION extends Structure { + public static final List FIELDS = createFieldsOrder( + "ByteLength", "ParentObjectTitleIndex", "ParentObjectInstance", + "UniqueID", "NameOffset", "NameLength"); + public int ByteLength; public int ParentObjectTitleIndex; public int ParentObjectInstance; @@ -69,12 +86,11 @@ @Override protected List getFieldOrder() { - return Arrays.asList("ByteLength", "ParentObjectTitleIndex", "ParentObjectInstance", - "UniqueID", "NameOffset", "NameLength"); + return FIELDS; } }; - public static final int PERF_NO_INSTANCES = -1; // no instances (see NumInstances above) + int PERF_NO_INSTANCES = -1; // no instances (see NumInstances above) // // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -96,121 +112,121 @@ // // select one of the following to indicate the counter's data size // - public static final int PERF_SIZE_DWORD = 0x00000000; // 32 bit field - public static final int PERF_SIZE_LARGE = 0x00000100; // 64 bit field - public static final int PERF_SIZE_ZERO = 0x00000200; // for Zero Length fields - public static final int PERF_SIZE_VARIABLE_LEN = 0x00000300; // length is in CounterLength field + int PERF_SIZE_DWORD = 0x00000000; // 32 bit field + int PERF_SIZE_LARGE = 0x00000100; // 64 bit field + int PERF_SIZE_ZERO = 0x00000200; // for Zero Length fields + int PERF_SIZE_VARIABLE_LEN = 0x00000300; // length is in CounterLength field // of Counter Definition struct // // select one of the following values to indicate the counter field usage // - public static final int PERF_TYPE_NUMBER = 0x00000000; // a number (not a counter) - public static final int PERF_TYPE_COUNTER = 0x00000400; // an increasing numeric value - public static final int PERF_TYPE_TEXT = 0x00000800; // a text field - public static final int PERF_TYPE_ZERO = 0x00000C00; // displays a zero + int PERF_TYPE_NUMBER = 0x00000000; // a number (not a counter) + int PERF_TYPE_COUNTER = 0x00000400; // an increasing numeric value + int PERF_TYPE_TEXT = 0x00000800; // a text field + int PERF_TYPE_ZERO = 0x00000C00; // displays a zero // // If the PERF_TYPE_NUMBER field was selected, then select one of the // following to describe the Number // - public static final int PERF_NUMBER_HEX = 0x00000000; // display as HEX value - public static final int PERF_NUMBER_DECIMAL = 0x00010000; // display as a decimal integer - public static final int PERF_NUMBER_DEC_1000 = 0x00020000; // display as a decimal/1000 + int PERF_NUMBER_HEX = 0x00000000; // display as HEX value + int PERF_NUMBER_DECIMAL = 0x00010000; // display as a decimal integer + int PERF_NUMBER_DEC_1000 = 0x00020000; // display as a decimal/1000 // // If the PERF_TYPE_COUNTER value was selected then select one of the // following to indicate the type of counter // - public static final int PERF_COUNTER_VALUE = 0x00000000; // display counter value - public static final int PERF_COUNTER_RATE = 0x00010000; // divide ctr / delta time - public static final int PERF_COUNTER_FRACTION = 0x00020000; // divide ctr / base - public static final int PERF_COUNTER_BASE = 0x00030000; // base value used in fractions - public static final int PERF_COUNTER_ELAPSED = 0x00040000; // subtract counter from current time - public static final int PERF_COUNTER_QUEUELEN = 0x00050000; // Use Queuelen processing func. - public static final int PERF_COUNTER_HISTOGRAM = 0x00060000; // Counter begins or ends a histogram - public static final int PERF_COUNTER_PRECISION = 0x00070000; // divide ctr / private clock + int PERF_COUNTER_VALUE = 0x00000000; // display counter value + int PERF_COUNTER_RATE = 0x00010000; // divide ctr / delta time + int PERF_COUNTER_FRACTION = 0x00020000; // divide ctr / base + int PERF_COUNTER_BASE = 0x00030000; // base value used in fractions + int PERF_COUNTER_ELAPSED = 0x00040000; // subtract counter from current time + int PERF_COUNTER_QUEUELEN = 0x00050000; // Use Queuelen processing func. + int PERF_COUNTER_HISTOGRAM = 0x00060000; // Counter begins or ends a histogram + int PERF_COUNTER_PRECISION = 0x00070000; // divide ctr / private clock // // If the PERF_TYPE_TEXT value was selected, then select one of the // following to indicate the type of TEXT data. // - public static final int PERF_TEXT_UNICODE = 0x00000000; // type of text in text field - public static final int PERF_TEXT_ASCII = 0x00010000; // ASCII using the CodePage field + int PERF_TEXT_UNICODE = 0x00000000; // type of text in text field + int PERF_TEXT_ASCII = 0x00010000; // ASCII using the CodePage field // // Timer SubTypes // - public static final int PERF_TIMER_TICK = 0x00000000; // use system perf. freq for base - public static final int PERF_TIMER_100NS = 0x00100000; // use 100 NS timer time base units - public static final int PERF_OBJECT_TIMER = 0x00200000; // use the object timer freq + int PERF_TIMER_TICK = 0x00000000; // use system perf. freq for base + int PERF_TIMER_100NS = 0x00100000; // use 100 NS timer time base units + int PERF_OBJECT_TIMER = 0x00200000; // use the object timer freq // // Any types that have calculations performed can use one or more of // the following calculation modification flags listed here // - public static final int PERF_DELTA_COUNTER = 0x00400000; // compute difference first - public static final int PERF_DELTA_BASE = 0x00800000; // compute base diff as well - public static final int PERF_INVERSE_COUNTER = 0x01000000; // show as 1.00-value (assumes: - public static final int PERF_MULTI_COUNTER = 0x02000000; // sum of multiple instances + int PERF_DELTA_COUNTER = 0x00400000; // compute difference first + int PERF_DELTA_BASE = 0x00800000; // compute base diff as well + int PERF_INVERSE_COUNTER = 0x01000000; // show as 1.00-value (assumes: + int PERF_MULTI_COUNTER = 0x02000000; // sum of multiple instances // // Select one of the following values to indicate the display suffix (if any) // - public static final int PERF_DISPLAY_NO_SUFFIX = 0x00000000; // no suffix - public static final int PERF_DISPLAY_PER_SEC = 0x10000000; // "/sec" - public static final int PERF_DISPLAY_PERCENT = 0x20000000; // "%" - public static final int PERF_DISPLAY_SECONDS = 0x30000000; // "secs" - public static final int PERF_DISPLAY_NOSHOW = 0x40000000; // value is not displayed + int PERF_DISPLAY_NO_SUFFIX = 0x00000000; // no suffix + int PERF_DISPLAY_PER_SEC = 0x10000000; // "/sec" + int PERF_DISPLAY_PERCENT = 0x20000000; // "%" + int PERF_DISPLAY_SECONDS = 0x30000000; // "secs" + int PERF_DISPLAY_NOSHOW = 0x40000000; // value is not displayed // // Predefined counter types // // 32-bit Counter. Divide delta by delta time. Display suffix: "/sec" - public static final int PERF_COUNTER_COUNTER = + int PERF_COUNTER_COUNTER = (PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_DISPLAY_PER_SEC); // 64-bit Timer. Divide delta by delta time. Display suffix: "%" - public static final int PERF_COUNTER_TIMER = + int PERF_COUNTER_TIMER = (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_DISPLAY_PERCENT); // Queue Length Space-Time Product. Divide delta by delta time. No Display Suffix. - public static final int PERF_COUNTER_QUEUELEN_TYPE = + int PERF_COUNTER_QUEUELEN_TYPE = (PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_QUEUELEN | PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_DISPLAY_NO_SUFFIX); // Queue Length Space-Time Product. Divide delta by delta time. No Display Suffix. - public static final int PERF_COUNTER_LARGE_QUEUELEN_TYPE = + int PERF_COUNTER_LARGE_QUEUELEN_TYPE = (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_QUEUELEN | PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_DISPLAY_NO_SUFFIX); // Queue Length Space-Time Product using 100 Ns timebase. // Divide delta by delta time. No Display Suffix. - public static final int PERF_COUNTER_100NS_QUEUELEN_TYPE = + int PERF_COUNTER_100NS_QUEUELEN_TYPE = (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_QUEUELEN | PERF_TIMER_100NS | PERF_DELTA_COUNTER | PERF_DISPLAY_NO_SUFFIX); // Queue Length Space-Time Product using Object specific timebase. // Divide delta by delta time. No Display Suffix. - public static final int PERF_COUNTER_OBJ_TIME_QUEUELEN_TYPE = + int PERF_COUNTER_OBJ_TIME_QUEUELEN_TYPE = (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_QUEUELEN | PERF_OBJECT_TIMER | PERF_DELTA_COUNTER | PERF_DISPLAY_NO_SUFFIX); // 64-bit Counter. Divide delta by delta time. Display Suffix: "/sec" - public static final int PERF_COUNTER_BULK_COUNT = + int PERF_COUNTER_BULK_COUNT = (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_DISPLAY_PER_SEC); // Indicates the counter is not a counter but rather Unicode text Display as text. - public static final int PERF_COUNTER_TEXT = + int PERF_COUNTER_TEXT = (PERF_SIZE_VARIABLE_LEN | PERF_TYPE_TEXT | PERF_TEXT_UNICODE | PERF_DISPLAY_NO_SUFFIX); // Indicates the data is a counter which should not be // time averaged on display (such as an error counter on a serial line) // Display as is. No Display Suffix. - public static final int PERF_COUNTER_RAWCOUNT = + int PERF_COUNTER_RAWCOUNT = (PERF_SIZE_DWORD | PERF_TYPE_NUMBER | PERF_NUMBER_DECIMAL | PERF_DISPLAY_NO_SUFFIX); // Same as PERF_COUNTER_RAWCOUNT except its size is a large integer - public static final int PERF_COUNTER_LARGE_RAWCOUNT = + int PERF_COUNTER_LARGE_RAWCOUNT = (PERF_SIZE_LARGE | PERF_TYPE_NUMBER | PERF_NUMBER_DECIMAL | PERF_DISPLAY_NO_SUFFIX); @@ -218,36 +234,36 @@ // Indicates the data is a counter which should not be // time averaged on display (such as an error counter on a serial line) // Display as is. No Display Suffix. - public static final int PERF_COUNTER_RAWCOUNT_HEX = + int PERF_COUNTER_RAWCOUNT_HEX = (PERF_SIZE_DWORD | PERF_TYPE_NUMBER | PERF_NUMBER_HEX | PERF_DISPLAY_NO_SUFFIX); // Same as PERF_COUNTER_RAWCOUNT_HEX except its size is a large integer - public static final int PERF_COUNTER_LARGE_RAWCOUNT_HEX = + int PERF_COUNTER_LARGE_RAWCOUNT_HEX = (PERF_SIZE_LARGE | PERF_TYPE_NUMBER | PERF_NUMBER_HEX | PERF_DISPLAY_NO_SUFFIX); // A count which is either 1 or 0 on each sampling interrupt (% busy) // Divide delta by delta base. Display Suffix: "%" - public static final int PERF_SAMPLE_FRACTION = + int PERF_SAMPLE_FRACTION = (PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_FRACTION | PERF_DELTA_COUNTER | PERF_DELTA_BASE | PERF_DISPLAY_PERCENT); // A count which is sampled on each sampling interrupt (queue length) // Divide delta by delta time. No Display Suffix. - public static final int PERF_SAMPLE_COUNTER = + int PERF_SAMPLE_COUNTER = (PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_DISPLAY_NO_SUFFIX); // A label: no data is associated with this counter (it has 0 length) // Do not display. - public static final int PERF_COUNTER_NODATA = + int PERF_COUNTER_NODATA = (PERF_SIZE_ZERO | PERF_DISPLAY_NOSHOW); // 64-bit Timer inverse (e.g., idle is measured, but display busy %) // Display 100 - delta divided by delta time. Display suffix: "%" - public static final int PERF_COUNTER_TIMER_INV = + int PERF_COUNTER_TIMER_INV = (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_INVERSE_COUNTER | PERF_DISPLAY_PERCENT); @@ -256,7 +272,7 @@ // sampled %. You must check for >0 before dividing by this! This // counter will directly follow the numerator counter. It should not // be displayed to the user. - public static final int PERF_SAMPLE_BASE = + int PERF_SAMPLE_BASE = (PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_BASE | PERF_DISPLAY_NOSHOW | 0x00000001); // for compatibility with pre-beta versions @@ -265,14 +281,14 @@ // in seconds which is the average time of some operation. This // timer times total operations, and the base is the number of opera- // tions. Display Suffix: "sec" - public static final int PERF_AVERAGE_TIMER = + int PERF_AVERAGE_TIMER = (PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_FRACTION | PERF_DISPLAY_SECONDS); // Used as the denominator in the computation of time or count // averages. Must directly follow the numerator counter. Not dis- // played to the user. - public static final int PERF_AVERAGE_BASE = + int PERF_AVERAGE_BASE = (PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_BASE | PERF_DISPLAY_NOSHOW | 0x00000002); // for compatibility with pre-beta versions @@ -281,33 +297,33 @@ // A bulk count which, when divided (typically) by the number of // operations, gives (typically) the number of bytes per operation. // No Display Suffix. - public static final int PERF_AVERAGE_BULK = + int PERF_AVERAGE_BULK = (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_FRACTION | PERF_DISPLAY_NOSHOW); // 64-bit Timer in object specific units. Display delta divided by // delta time as returned in the object type header structure. Display suffix: "%" - public static final int PERF_OBJ_TIME_TIMER = + int PERF_OBJ_TIME_TIMER = (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_OBJECT_TIMER | PERF_DELTA_COUNTER | PERF_DISPLAY_PERCENT); // 64-bit Timer in 100 nsec units. Display delta divided by // delta time. Display suffix: "%" - public static final int PERF_100NSEC_TIMER = + int PERF_100NSEC_TIMER = (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_100NS | PERF_DELTA_COUNTER | PERF_DISPLAY_PERCENT); // 64-bit Timer inverse (e.g., idle is measured, but display busy %) // Display 100 - delta divided by delta time. Display suffix: "%" - public static final int PERF_100NSEC_TIMER_INV = + int PERF_100NSEC_TIMER_INV = (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_100NS | PERF_DELTA_COUNTER | PERF_INVERSE_COUNTER | PERF_DISPLAY_PERCENT); // 64-bit Timer. Divide delta by delta time. Display suffix: "%" // Timer for multiple instances, so result can exceed 100%. - public static final int PERF_COUNTER_MULTI_TIMER = + int PERF_COUNTER_MULTI_TIMER = (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_DELTA_COUNTER | PERF_TIMER_TICK | PERF_MULTI_COUNTER | PERF_DISPLAY_PERCENT); @@ -316,20 +332,20 @@ // Display 100 * _MULTI_BASE - delta divided by delta time. // Display suffix: "%" Timer for multiple instances, so result // can exceed 100%. Followed by a counter of type _MULTI_BASE. - public static final int PERF_COUNTER_MULTI_TIMER_INV = + int PERF_COUNTER_MULTI_TIMER_INV = (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_DELTA_COUNTER | PERF_MULTI_COUNTER | PERF_TIMER_TICK | PERF_INVERSE_COUNTER | PERF_DISPLAY_PERCENT); // Number of instances to which the preceding _MULTI_..._INV counter // applies. Used as a factor to get the percentage. - public static final int PERF_COUNTER_MULTI_BASE = + int PERF_COUNTER_MULTI_BASE = (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_BASE | PERF_MULTI_COUNTER | PERF_DISPLAY_NOSHOW); // 64-bit Timer in 100 nsec units. Display delta divided by delta time. // Display suffix: "%" Timer for multiple instances, so result can exceed 100%. - public static final int PERF_100NSEC_MULTI_TIMER = + int PERF_100NSEC_MULTI_TIMER = (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_DELTA_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_100NS | PERF_MULTI_COUNTER | PERF_DISPLAY_PERCENT); @@ -338,7 +354,7 @@ // Display 100 * _MULTI_BASE - delta divided by delta time. // Display suffix: "%" Timer for multiple instances, so result // can exceed 100%. Followed by a counter of type _MULTI_BASE. - public static final int PERF_100NSEC_MULTI_TIMER_INV = + int PERF_100NSEC_MULTI_TIMER_INV = (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_DELTA_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_100NS | PERF_MULTI_COUNTER | PERF_INVERSE_COUNTER | PERF_DISPLAY_PERCENT); @@ -346,22 +362,22 @@ // Indicates the data is a fraction of the following counter which // should not be time averaged on display (such as free space over // total space.) Display as is. Display the quotient as "%". - public static final int PERF_RAW_FRACTION = + int PERF_RAW_FRACTION = (PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_FRACTION | PERF_DISPLAY_PERCENT); - public static final int PERF_LARGE_RAW_FRACTION = + int PERF_LARGE_RAW_FRACTION = (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_FRACTION | PERF_DISPLAY_PERCENT); // Indicates the data is a base for the preceding counter which should // not be time averaged on display (such as free space over total space.) - public static final int PERF_RAW_BASE = + int PERF_RAW_BASE = (PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_BASE | PERF_DISPLAY_NOSHOW | 0x00000003); // for compatibility with pre-beta versions - public static final int PERF_LARGE_RAW_BASE = + int PERF_LARGE_RAW_BASE = (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_BASE | PERF_DISPLAY_NOSHOW ); @@ -372,7 +388,7 @@ // the sample time as indicated by the PERF_OBJECT_TIMER bit and the // difference is scaled by the PerfFreq of the Object to convert the time // units into seconds. - public static final int PERF_ELAPSED_TIME = + int PERF_ELAPSED_TIME = (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_ELAPSED | PERF_OBJECT_TIMER | PERF_DISPLAY_SECONDS); // @@ -380,7 +396,7 @@ // define a range of values to be displayed in a histogram. // - public static final int PERF_COUNTER_HISTOGRAM_TYPE = 0x80000000; // Counter begins or ends a histogram + int PERF_COUNTER_HISTOGRAM_TYPE = 0x80000000; // Counter begins or ends a histogram // // This counter is used to display the difference from one sample // to the next. The counter value is a constantly increasing number @@ -389,11 +405,11 @@ // which shouldn't be a problem as long as the counter value is // increasing or unchanged. // - public static final int PERF_COUNTER_DELTA = + int PERF_COUNTER_DELTA = (PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_VALUE | PERF_DELTA_COUNTER | PERF_DISPLAY_NO_SUFFIX); - public static final int PERF_COUNTER_LARGE_DELTA = + int PERF_COUNTER_LARGE_DELTA = (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_VALUE | PERF_DELTA_COUNTER | PERF_DISPLAY_NO_SUFFIX); // @@ -414,38 +430,38 @@ // definition of the PERF_PRECISION_*_TIMER in the Object header // // The timer used has the same frequency as the System Performance Timer - public static final int PERF_PRECISION_SYSTEM_TIMER = - (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_PRECISION | + int PERF_PRECISION_SYSTEM_TIMER = + (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_PRECISION | PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_DISPLAY_PERCENT ); // // The timer used has the same frequency as the 100 NanoSecond Timer - public static final int PERF_PRECISION_100NS_TIMER = - (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_PRECISION | + int PERF_PRECISION_100NS_TIMER = + (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_PRECISION | PERF_TIMER_100NS | PERF_DELTA_COUNTER | PERF_DISPLAY_PERCENT ); // // The timer used is of the frequency specified in the Object header's // PerfFreq field (PerfTime is ignored) - public static final int PERF_PRECISION_OBJECT_TIMER = - (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_PRECISION | + int PERF_PRECISION_OBJECT_TIMER = + (PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_PRECISION | PERF_OBJECT_TIMER | PERF_DELTA_COUNTER | PERF_DISPLAY_PERCENT ); // // This is the timestamp to use in the computation of the timer specified // in the previous description block - public static final int PERF_PRECISION_TIMESTAMP = PERF_LARGE_RAW_BASE; + int PERF_PRECISION_TIMESTAMP = PERF_LARGE_RAW_BASE; // // The following are used to determine the level of detail associated // with the counter. The user will be setting the level of detail // that should be displayed at any given time. // // - public static final int PERF_DETAIL_NOVICE = 100; // The uninformed can understand it - public static final int PERF_DETAIL_ADVANCED = 200; // For the advanced user - public static final int PERF_DETAIL_EXPERT = 300; // For the expert user - public static final int PERF_DETAIL_WIZARD = 400; // For the system designer - - public static final int PERF_NO_UNIQUE_ID = -1; - - public static final int PERF_QUERY_OBJECTS = 0x80000000; - public static final int PERF_QUERY_GLOBAL = 0x80000001; - public static final int PERF_QUERY_COSTLY = 0x80000002; + int PERF_DETAIL_NOVICE = 100; // The uninformed can understand it + int PERF_DETAIL_ADVANCED = 200; // For the advanced user + int PERF_DETAIL_EXPERT = 300; // For the expert user + int PERF_DETAIL_WIZARD = 400; // For the system designer + + int PERF_NO_UNIQUE_ID = -1; + + int PERF_QUERY_OBJECTS = 0x80000000; + int PERF_QUERY_GLOBAL = 0x80000001; + int PERF_QUERY_COSTLY = 0x80000002; } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/WinRas.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/WinRas.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/WinRas.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/WinRas.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2011 Timothy Wall, 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * You can freely decide which license you want to apply to + * the project. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; @@ -26,12 +37,12 @@ import com.sun.jna.platform.win32.WinDef.HWND; import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.platform.win32.WinNT.LUID; -import com.sun.jna.win32.StdCallLibrary; +import com.sun.jna.win32.StdCallLibrary.StdCallCallback; /** * Definitions for RASAPI32 */ -public interface WinRas extends StdCallLibrary { +public interface WinRas { public static final int ERROR_BUFFER_TOO_SMALL = 603; public static final int ERROR_CANNOT_FIND_PHONEBOOK_ENTRY = 623; @@ -99,9 +110,8 @@ */ public Pointer pbEapInfo; - @SuppressWarnings("rawtypes") @Override - protected List getFieldOrder() { + protected List getFieldOrder() { return Arrays.asList(new String[] { "dwSizeofEapInfo", "pbEapInfo", }); } /** @@ -148,9 +158,8 @@ */ public Pointer pbDevSpecificInfo; - @SuppressWarnings("rawtypes") @Override - protected List getFieldOrder() { + protected List getFieldOrder() { return Arrays.asList(new String[] { "dwSize", "pbDevSpecificInfo", }); } /** @@ -219,9 +228,8 @@ */ public RASDEVSPECIFICINFO RasDevSpecificInfo; - @SuppressWarnings("rawtypes") @Override - protected List getFieldOrder() { + protected List getFieldOrder() { return Arrays.asList(new String[] { "dwSize", "dwfOptions", "hwndParent", "reserved", "reserved1", "RasEapInfo", "fSkipPppAuth", "RasDevSpecificInfo", }); } } @@ -277,9 +285,8 @@ */ public char[] szDomain = new char[DNLEN + 1]; - @SuppressWarnings("rawtypes") @Override - protected List getFieldOrder() { + protected List getFieldOrder() { return Arrays.asList(new String[] { "dwSize", "szEntryName", "szPhoneNumber", "szCallbackNumber", "szUserName", "szPassword", "szDomain", }); } } @@ -348,9 +355,8 @@ */ public GUID guidCorrelationId; - @SuppressWarnings("rawtypes") @Override - protected List getFieldOrder() { + protected List getFieldOrder() { return Arrays.asList(new String[] { "dwSize", "hrasconn", "szEntryName", "szDeviceType", "szDeviceName", "szPhonebook", "dwSubEntry", "guidEntry", "dwFlags", "luid", "guidCorrelationId" }); } } @@ -430,9 +436,8 @@ */ public int dwConnectDuration; - @SuppressWarnings("rawtypes") @Override - protected List getFieldOrder() { + protected List getFieldOrder() { return Arrays.asList(new String[] { "dwSize", "dwBytesXmited", "dwBytesRcved", "dwFramesXmited", "dwFramesRcved", "dwCrcErr", "dwTimeoutErr", "dwAlignmentErr", "dwHardwareOverrunErr", "dwFramingErr", "dwBufferOverrunErr", "dwCompressionRatioIn", "dwCompressionRatioOut", "dwBps", "dwConnectDuration", }); } } @@ -455,9 +460,8 @@ */ public byte[] addr = new byte[8]; - @SuppressWarnings("rawtypes") @Override - protected List getFieldOrder() { + protected List getFieldOrder() { return Arrays.asList(new String[] { "addr", }); } } @@ -480,9 +484,8 @@ */ public byte[] addr = new byte[16]; - @SuppressWarnings("rawtypes") @Override - protected List getFieldOrder() { + protected List getFieldOrder() { return Arrays.asList(new String[] { "addr", }); } } @@ -534,9 +537,8 @@ */ public int dwServerOptions; - @SuppressWarnings("rawtypes") @Override - protected List getFieldOrder() { + protected List getFieldOrder() { return Arrays.asList(new String[] { "dwSize", "dwError", "szIpAddress", "szServerIpAddress", "dwOptions", "dwServerOptions",}); } } @@ -572,9 +574,8 @@ */ public UNION u; - @SuppressWarnings("rawtypes") @Override - protected List getFieldOrder() { + protected List getFieldOrder() { return Arrays.asList(new String[] { "dwType", "u", }); } @@ -654,9 +655,8 @@ */ public int rasconnsubstate; - @SuppressWarnings("rawtypes") @Override - protected List getFieldOrder() { + protected List getFieldOrder() { return Arrays.asList(new String[] { "dwSize", "rasconnstate", "dwError", "szDeviceType", "szDeviceName", "szPhoneNumber", "localEndPoint", "remoteEndPoint", "rasconnsubstate" }); } } @@ -699,9 +699,8 @@ */ public char[] szDomain = new char[DNLEN + 1]; - @SuppressWarnings("rawtypes") @Override - protected List getFieldOrder() { + protected List getFieldOrder() { return Arrays.asList(new String[] { "dwSize", "dwMask", "szUserName", "szPassword", "szDomain", }); } } @@ -722,9 +721,8 @@ public byte[] addr = new byte[4]; - @SuppressWarnings("rawtypes") @Override - protected List getFieldOrder() { + protected List getFieldOrder() { return Arrays.asList(new String[] { "addr", }); } } @@ -1016,9 +1014,8 @@ */ public int dwNetworkOutageTime; - @SuppressWarnings("rawtypes") @Override - protected List getFieldOrder() { + protected List getFieldOrder() { return Arrays.asList(new String[] { "dwSize", "dwfOptions", "dwCountryID", "dwCountryCode", "szAreaCode", "szLocalPhoneNumber", "dwAlternateOffset", "ipaddr", "ipaddrDns", "ipaddrDnsAlt", "ipaddrWins", "ipaddrWinsAlt", "dwFrameSize", "dwfNetProtocols", "dwFramingProtocol", "szScript", "szAutodialDll", "szAutodialFunc", "szDeviceType", "szDeviceName", "szX25PadType", "szX25Address", "szX25Facilities", "szX25UserData" , diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/WinReg.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/WinReg.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/WinReg.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/WinReg.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,21 +1,31 @@ /* Copyright (c) 2010 Daniel Doubrovkine, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.Pointer; import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.ptr.ByReference; -import com.sun.jna.win32.StdCallLibrary; /** * This module contains the function prototypes and constant, type and structure @@ -24,7 +34,7 @@ * Microsoft Windows SDK 6.0A. * @author dblock[at]dblock.org */ -public interface WinReg extends StdCallLibrary { +public interface WinReg { public static class HKEY extends HANDLE { public HKEY() { } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Winspool.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2010 Daniel Doubrovkine, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * 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). * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; @@ -22,6 +33,7 @@ import com.sun.jna.platform.win32.WinBase.SYSTEMTIME; import com.sun.jna.platform.win32.WinDef.DWORD; import com.sun.jna.platform.win32.WinDef.DWORDByReference; +import com.sun.jna.platform.win32.WinDef.INT_PTR; import com.sun.jna.platform.win32.WinDef.LPVOID; import com.sun.jna.platform.win32.WinDef.PVOID; import com.sun.jna.platform.win32.WinNT.HANDLE; @@ -37,63 +49,110 @@ */ public interface Winspool extends StdCallLibrary { - public final static int CCHDEVICENAME = 32; + Winspool INSTANCE = Native.loadLibrary("Winspool.drv", Winspool.class, W32APIOptions.DEFAULT_OPTIONS); - public final static int PRINTER_CHANGE_ADD_PRINTER = 0x00000001; - public final static int PRINTER_CHANGE_SET_PRINTER = 0x00000002; - public final static int PRINTER_CHANGE_DELETE_PRINTER = 0x00000004; - public final static int PRINTER_CHANGE_FAILED_CONNECTION_PRINTER = 0x00000008; - public final static int PRINTER_CHANGE_PRINTER = 0x000000FF; - public final static int PRINTER_CHANGE_ADD_JOB = 0x00000100; - public final static int PRINTER_CHANGE_SET_JOB = 0x00000200; - public final static int PRINTER_CHANGE_DELETE_JOB = 0x00000400; - public final static int PRINTER_CHANGE_WRITE_JOB = 0x00000800; - public final static int PRINTER_CHANGE_JOB = 0x0000FF00; - public final static int PRINTER_CHANGE_ADD_FORM = 0x00010000; - public final static int PRINTER_CHANGE_SET_FORM = 0x00020000; - public final static int PRINTER_CHANGE_DELETE_FORM = 0x00040000; - public final static int PRINTER_CHANGE_FORM = 0x00070000; - public final static int PRINTER_CHANGE_ADD_PORT = 0x00100000; - public final static int PRINTER_CHANGE_CONFIGURE_PORT = 0x00200000; - public final static int PRINTER_CHANGE_DELETE_PORT = 0x00400000; - public final static int PRINTER_CHANGE_PORT = 0x00700000; - public final static int PRINTER_CHANGE_ADD_PRINT_PROCESSOR = 0x01000000; - public final static int PRINTER_CHANGE_DELETE_PRINT_PROCESSOR = 0x04000000; - public final static int PRINTER_CHANGE_PRINT_PROCESSOR = 0x07000000; - public final static int PRINTER_CHANGE_SERVER = 0x08000000; - public final static int PRINTER_CHANGE_ADD_PRINTER_DRIVER = 0x10000000; - public final static int PRINTER_CHANGE_SET_PRINTER_DRIVER = 0x20000000; - public final static int PRINTER_CHANGE_DELETE_PRINTER_DRIVER = 0x40000000; - public final static int PRINTER_CHANGE_PRINTER_DRIVER = 0x70000000; - public final static int PRINTER_CHANGE_TIMEOUT = 0x80000000; - public final static int PRINTER_CHANGE_ALL_WIN7 = 0x7F77FFFF; - public final static int PRINTER_CHANGE_ALL = 0x7777FFFF; - - int PRINTER_ENUM_DEFAULT = 0x00000001; - int PRINTER_ENUM_LOCAL = 0x00000002; - int PRINTER_ENUM_CONNECTIONS = 0x00000004; - int PRINTER_ENUM_FAVORITE = 0x00000004; - int PRINTER_ENUM_NAME = 0x00000008; - int PRINTER_ENUM_REMOTE = 0x00000010; - int PRINTER_ENUM_SHARED = 0x00000020; - int PRINTER_ENUM_NETWORK = 0x00000040; - - int PRINTER_ENUM_EXPAND = 0x00004000; - int PRINTER_ENUM_CONTAINER = 0x00008000; - - int PRINTER_ENUM_ICONMASK = 0x00ff0000; - int PRINTER_ENUM_ICON1 = 0x00010000; - int PRINTER_ENUM_ICON2 = 0x00020000; - int PRINTER_ENUM_ICON3 = 0x00040000; - int PRINTER_ENUM_ICON4 = 0x00080000; - int PRINTER_ENUM_ICON5 = 0x00100000; - int PRINTER_ENUM_ICON6 = 0x00200000; - int PRINTER_ENUM_ICON7 = 0x00400000; - int PRINTER_ENUM_ICON8 = 0x00800000; - int PRINTER_ENUM_HIDE = 0x01000000; + public static final int CCHDEVICENAME = 32; - Winspool INSTANCE = (Winspool) Native.loadLibrary("Winspool.drv", - Winspool.class, W32APIOptions.UNICODE_OPTIONS); + public static final int PRINTER_STATUS_PAUSED = 0x00000001; + public static final int PRINTER_STATUS_ERROR = 0x00000002; + public static final int PRINTER_STATUS_PENDING_DELETION = 0x00000004; + public static final int PRINTER_STATUS_PAPER_JAM = 0x00000008; + public static final int PRINTER_STATUS_PAPER_OUT = 0x00000010; + public static final int PRINTER_STATUS_MANUAL_FEED = 0x00000020; + public static final int PRINTER_STATUS_PAPER_PROBLEM = 0x00000040; + public static final int PRINTER_STATUS_OFFLINE = 0x00000080; + public static final int PRINTER_STATUS_IO_ACTIVE = 0x00000100; + public static final int PRINTER_STATUS_BUSY = 0x00000200; + public static final int PRINTER_STATUS_PRINTING = 0x00000400; + public static final int PRINTER_STATUS_OUTPUT_BIN_FULL = 0x00000800; + public static final int PRINTER_STATUS_NOT_AVAILABLE = 0x00001000; + public static final int PRINTER_STATUS_WAITING = 0x00002000; + public static final int PRINTER_STATUS_PROCESSING = 0x00004000; + public static final int PRINTER_STATUS_INITIALIZING = 0x00008000; + public static final int PRINTER_STATUS_WARMING_UP = 0x00010000; + public static final int PRINTER_STATUS_TONER_LOW = 0x00020000; + public static final int PRINTER_STATUS_NO_TONER = 0x00040000; + public static final int PRINTER_STATUS_PAGE_PUNT = 0x00080000; + public static final int PRINTER_STATUS_USER_INTERVENTION = 0x00100000; + public static final int PRINTER_STATUS_OUT_OF_MEMORY = 0x00200000; + public static final int PRINTER_STATUS_DOOR_OPEN = 0x00400000; + public static final int PRINTER_STATUS_SERVER_UNKNOWN = 0x00800000; + public static final int PRINTER_STATUS_POWER_SAVE = 0x01000000; + + public static final int PRINTER_ATTRIBUTE_QUEUED = 0x00000001; + public static final int PRINTER_ATTRIBUTE_DIRECT = 0x00000002; + public static final int PRINTER_ATTRIBUTE_DEFAULT = 0x00000004; + public static final int PRINTER_ATTRIBUTE_SHARED = 0x00000008; + public static final int PRINTER_ATTRIBUTE_NETWORK = 0x00000010; + public static final int PRINTER_ATTRIBUTE_HIDDEN = 0x00000020; + public static final int PRINTER_ATTRIBUTE_LOCAL = 0x00000040; + public static final int PRINTER_ATTRIBUTE_ENABLE_DEVQ = 0x00000080; + public static final int PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS = 0x00000100; + public static final int PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST = 0x00000200; + public static final int PRINTER_ATTRIBUTE_WORK_OFFLINE = 0x00000400; + public static final int PRINTER_ATTRIBUTE_ENABLE_BIDI = 0x00000800; + public static final int PRINTER_ATTRIBUTE_RAW_ONLY = 0x00001000; + public static final int PRINTER_ATTRIBUTE_PUBLISHED = 0x00002000; + public static final int PRINTER_ATTRIBUTE_FAX = 0x00004000; + public static final int PRINTER_ATTRIBUTE_TS = 0x00008000; + public static final int PRINTER_ATTRIBUTE_PUSHED_USER = 0x00020000; + public static final int PRINTER_ATTRIBUTE_PUSHED_MACHINE = 0x00040000; + public static final int PRINTER_ATTRIBUTE_MACHINE = 0x00080000; + public static final int PRINTER_ATTRIBUTE_FRIENDLY_NAME = 0x00100000; + public static final int PRINTER_ATTRIBUTE_TS_GENERIC_DRIVER = 0x00200000; + + public static final int PRINTER_CHANGE_ADD_PRINTER = 0x00000001; + public static final int PRINTER_CHANGE_SET_PRINTER = 0x00000002; + public static final int PRINTER_CHANGE_DELETE_PRINTER = 0x00000004; + public static final int PRINTER_CHANGE_FAILED_CONNECTION_PRINTER = 0x00000008; + public static final int PRINTER_CHANGE_PRINTER = 0x000000FF; + public static final int PRINTER_CHANGE_ADD_JOB = 0x00000100; + public static final int PRINTER_CHANGE_SET_JOB = 0x00000200; + public static final int PRINTER_CHANGE_DELETE_JOB = 0x00000400; + public static final int PRINTER_CHANGE_WRITE_JOB = 0x00000800; + public static final int PRINTER_CHANGE_JOB = 0x0000FF00; + public static final int PRINTER_CHANGE_ADD_FORM = 0x00010000; + public static final int PRINTER_CHANGE_SET_FORM = 0x00020000; + public static final int PRINTER_CHANGE_DELETE_FORM = 0x00040000; + public static final int PRINTER_CHANGE_FORM = 0x00070000; + public static final int PRINTER_CHANGE_ADD_PORT = 0x00100000; + public static final int PRINTER_CHANGE_CONFIGURE_PORT = 0x00200000; + public static final int PRINTER_CHANGE_DELETE_PORT = 0x00400000; + public static final int PRINTER_CHANGE_PORT = 0x00700000; + public static final int PRINTER_CHANGE_ADD_PRINT_PROCESSOR = 0x01000000; + public static final int PRINTER_CHANGE_DELETE_PRINT_PROCESSOR = 0x04000000; + public static final int PRINTER_CHANGE_PRINT_PROCESSOR = 0x07000000; + public static final int PRINTER_CHANGE_SERVER = 0x08000000; + public static final int PRINTER_CHANGE_ADD_PRINTER_DRIVER = 0x10000000; + public static final int PRINTER_CHANGE_SET_PRINTER_DRIVER = 0x20000000; + public static final int PRINTER_CHANGE_DELETE_PRINTER_DRIVER = 0x40000000; + public static final int PRINTER_CHANGE_PRINTER_DRIVER = 0x70000000; + public static final int PRINTER_CHANGE_TIMEOUT = 0x80000000; + public static final int PRINTER_CHANGE_ALL_WIN7 = 0x7F77FFFF; + public static final int PRINTER_CHANGE_ALL = 0x7777FFFF; + + public static final int PRINTER_ENUM_DEFAULT = 0x00000001; + public static final int PRINTER_ENUM_LOCAL = 0x00000002; + public static final int PRINTER_ENUM_CONNECTIONS = 0x00000004; + public static final int PRINTER_ENUM_FAVORITE = 0x00000004; + public static final int PRINTER_ENUM_NAME = 0x00000008; + public static final int PRINTER_ENUM_REMOTE = 0x00000010; + public static final int PRINTER_ENUM_SHARED = 0x00000020; + public static final int PRINTER_ENUM_NETWORK = 0x00000040; + + public static final int PRINTER_ENUM_EXPAND = 0x00004000; + public static final int PRINTER_ENUM_CONTAINER = 0x00008000; + + public static final int PRINTER_ENUM_ICONMASK = 0x00ff0000; + public static final int PRINTER_ENUM_ICON1 = 0x00010000; + public static final int PRINTER_ENUM_ICON2 = 0x00020000; + public static final int PRINTER_ENUM_ICON3 = 0x00040000; + public static final int PRINTER_ENUM_ICON4 = 0x00080000; + public static final int PRINTER_ENUM_ICON5 = 0x00100000; + public static final int PRINTER_ENUM_ICON6 = 0x00200000; + public static final int PRINTER_ENUM_ICON7 = 0x00400000; + public static final int PRINTER_ENUM_ICON8 = 0x00800000; + public static final int PRINTER_ENUM_HIDE = 0x01000000; /** * The EnumPrinters function enumerates available printers, print servers, @@ -155,56 +214,325 @@ * array to which pPrinterEnum points. * @return If the function succeeds, the return value is a nonzero value. If * the function fails, the return value is zero. - */ + * + * @see + * EnumPrinters function + */ boolean EnumPrinters(int Flags, String Name, int Level, Pointer pPrinterEnum, int cbBuf, IntByReference pcbNeeded, IntByReference pcReturned); + + /** + * The GetPrinter function retrieves information about a specified printer. + * + * @param hPrinter + * A handle to the printer for which the function retrieves + * information. Use the OpenPrinter or AddPrinter function to + * retrieve a printer handle. + * @param Level + * The level or type of structure that the function stores into + * the buffer pointed to by pPrinter. This value can be 1, 2, 3, + * 4, 5, 6, 7, 8 or 9. + * @param pPrinter + * A pointer to a buffer that receives a structure containing + * information about the specified printer. The buffer must be + * large enough to receive the structure and any strings or other + * data to which the structure members point. If the buffer is + * too small, the pcbNeeded parameter returns the required buffer + * size. The type of structure is determined by the value of + * Level. + * @param cbBuf + * The size, in bytes, of the buffer pointed to by pPrinter. + * @param pcbNeeded + * A pointer to a variable that the function sets to the size, in + * bytes, of the printer information. If cbBuf is smaller than + * this value, GetPrinter fails, and the value represents the + * required buffer size. If cbBuf is equal to or greater than + * this value, GetPrinter succeeds, and the value represents the + * number of bytes stored in the buffer. + * @return If the function succeeds, the return value is a nonzero value. If + * the function fails, the return value is zero. + * + * @see + * GetPrinter function + */ + boolean GetPrinter(HANDLE hPrinter, int Level, Pointer pPrinter, int cbBuf, IntByReference pcbNeeded); + + /** + * The PRINTER_INFO_1 structure specifies general printer information. + * + * @see + * PRINTER_INFO_1 structure + */ + public static class PRINTER_INFO_1 extends Structure { + + public static final List FIELDS = createFieldsOrder("Flags", "pDescription", "pName", "pComment"); + + /** + * Specifies information about the returned data. Following are the + * values for this member. + */ + public int Flags; + /** + * Pointer to a null-terminated string that describes the contents of + * the structure. + */ + public String pDescription; + /** + * Pointer to a null-terminated string that names the contents of the + * structure. + */ + public String pName; + /** + * Pointer to a null-terminated string that contains additional data + * describing the structure. + */ + public String pComment; - public static class PRINTER_INFO_1 extends Structure { - public int Flags; - public String pDescription; - public String pName; - public String pComment; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "Flags", "pDescription", - "pName", "pComment" }); - } - - public PRINTER_INFO_1() { + public PRINTER_INFO_1() { + super(); } public PRINTER_INFO_1(int size) { super(new Memory(size)); } - } - - public static class PRINTER_INFO_4 extends Structure { - public String pPrinterName; - public String pServerName; - public DWORD Attributes; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "pPrinterName", "pServerName", - "Attributes" }); + @Override + protected List getFieldOrder() { + return FIELDS; } + } + + /** + * The PRINTER_INFO_2 structure specifies detailed printer information. + * + * @author Ivan Ridao Freitas, Padrus + * @see + * PRINTER_INFO_2 structure + */ + public static class PRINTER_INFO_2 extends Structure { + + public static final List FIELDS = createFieldsOrder("pServerName", "pPrinterName", "pShareName", + "pPortName", "pDriverName", "pComment", "pLocation", "pDevMode", "pSepFile", "pPrintProcessor", + "pDatatype", "pParameters", "pSecurityDescriptor", "Attributes", "Priority", "DefaultPriority", + "StartTime", "UntilTime", "Status", "cJobs", "AveragePPM"); + + /** + * A pointer to a null-terminated string identifying the server that + * controls the printer. If this string is NULL, the printer is + * controlled locally. + */ + public String pServerName; + /** + * A pointer to a null-terminated string that specifies the name of the + * printer. + */ + public String pPrinterName; + /** + * A pointer to a null-terminated string that identifies the share point + * for the printer. (This string is used only if the + * PRINTER_ATTRIBUTE_SHARED constant was set for the Attributes member.) + */ + public String pShareName; + /** + * A pointer to a null-terminated string that identifies the port(s) + * used to transmit data to the printer. If a printer is connected to + * more than one port, the names of each port must be separated by + * commas (for example, "LPT1:,LPT2:,LPT3:"). + */ + public String pPortName; + /** + * A pointer to a null-terminated string that specifies the name of the + * printer driver. + */ + public String pDriverName; + /** + * A pointer to a null-terminated string that provides a brief + * description of the printer. + */ + public String pComment; + /** + * A pointer to a null-terminated string that specifies the physical + * location of the printer (for example, "Bldg. 38, Room 1164"). + */ + public String pLocation; + /** + * A pointer to a DEVMODE structure that defines default printer data + * such as the paper orientation and the resolution. + */ + public INT_PTR pDevMode; + /** + * A pointer to a null-terminated string that specifies the name of the + * file used to create the separator page. This page is used to separate + * print jobs sent to the printer. + */ + public String pSepFile; + /** + * A pointer to a null-terminated string that specifies the name of the + * print processor used by the printer. You can use the + * EnumPrintProcessors function to obtain a list of print processors + * installed on a server. + */ + public String pPrintProcessor; + /** + * A pointer to a null-terminated string that specifies the data type + * used to record the print job. You can use the + * EnumPrintProcessorDatatypes function to obtain a list of data types + * supported by a specific print processor. + */ + public String pDatatype; + /** + * A pointer to a null-terminated string that specifies the default + * print-processor parameters. + */ + public String pParameters; + /** + * A pointer to a SECURITY_DESCRIPTOR structure for the printer. This + * member may be NULL. + */ + public INT_PTR pSecurityDescriptor; + /** + * The printer attributes. This member can be any reasonable combination + * of the values PRINTER_ATTRIBUTE_XXX. + */ + public int Attributes; + /** + * A priority value that the spooler uses to route print jobs. + */ + public int Priority; + /** + * The default priority value assigned to each print job. + */ + public int DefaultPriority; + /** + * The earliest time at which the printer will print a job. This value + * is expressed as minutes elapsed since 12:00 AM GMT (Greenwich Mean + * Time). + */ + public int StartTime; + /** + * The latest time at which the printer will print a job. This value is + * expressed as minutes elapsed since 12:00 AM GMT (Greenwich Mean + * Time). + */ + public int UntilTime; + /** + * The printer status. This member can be any reasonable combination of + * the values PRINTER_STATUS_XXX. + */ + public int Status; + /** + * The number of print jobs that have been queued for the printer. + */ + public int cJobs; + /** + * The average number of pages per minute that have been printed on the + * printer. + */ + public int AveragePPM; + + public PRINTER_INFO_2() { + super(); + } + + public PRINTER_INFO_2(int size) { + super(new Memory(size)); + } + + @Override + protected List getFieldOrder() { + return FIELDS; + } + + /** + * Checks if the printer attributes have one of the values PRINTER_ATTRIBUTE_XXX. + */ + public boolean hasAttribute(int value) { + return (Attributes & value) == value; + } + } + + /** + * The PRINTER_INFO_4 structure specifies general printer information. + *

    + * The structure can be used to retrieve minimal printer information on a + * call to EnumPrinters. Such a call is a fast and easy way to retrieve the + * names and attributes of all locally installed printers on a system and + * all remote printer connections that a user has established. + * + * @see + * PRINTER_INFO_4 structure + */ + public static class PRINTER_INFO_4 extends Structure { + + public static final List FIELDS = createFieldsOrder("pPrinterName", "pServerName", "Attributes"); + + /** + * Pointer to a null-terminated string that specifies the name of the + * printer (local or remote). + */ + public String pPrinterName; + /** + * Pointer to a null-terminated string that is the name of the server. + */ + public String pServerName; + /** + * Specifies information about the returned data. + */ + public DWORD Attributes; - public PRINTER_INFO_4() { + public PRINTER_INFO_4() { + super(); } public PRINTER_INFO_4(int size) { super(new Memory(size)); } + + @Override + protected List getFieldOrder() { + return FIELDS; + } } - public class LPPRINTER_DEFAULTS extends Structure { - public String pDatatype; - PVOID pDevMode; - int DesiredAccess; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "pDatatype", "pDevMode", - "DesiredAccess" }); + /** + * The PRINTER_DEFAULTS structure specifies the default data type, + * environment, initialization data, and access rights for a printer. + * + * @see + * PRINTER_DEFAULTS structure + */ + public class LPPRINTER_DEFAULTS extends Structure { + + public static final List FIELDS = createFieldsOrder("pDatatype", "pDevMode", "DesiredAccess"); + + /** + * Pointer to a null-terminated string that specifies the default data + * type for a printer. + */ + public String pDatatype; + /** + * Pointer to a DEVMODE structure that identifies the default + * environment and initialization data for a printer. + */ + PVOID pDevMode; + /** + * Specifies desired access rights for a printer. The OpenPrinter + * function uses this member to set access rights to the printer. These + * rights can affect the operation of the SetPrinter and DeletePrinter + * functions. + */ + int DesiredAccess; + + @Override + protected List getFieldOrder() { + return FIELDS; } } @@ -212,8 +540,6 @@ * The OpenPrinter function retrieves a handle to the specified printer or * print server or other types of handles in the print subsystem. * - * @see MSDN - * * @param pPrinterName * [in] A pointer to a null-terminated string that specifies the * name of the printer or print server, the printer object, the @@ -233,15 +559,45 @@ * be NULL. * @return If the function succeeds, the return value is a nonzero value. If * the function fails, the return value is zero. - */ + * + * @see + * OpenPrinter function + */ boolean OpenPrinter( - // _In_ + // _In_ String pPrinterName, // _Out_ HANDLEByReference phPrinter, // _In_ LPPRINTER_DEFAULTS pDefault); + /** + * The ClosePrinter function closes the specified printer object.
    + * Note This is a blocking or synchronous function and might not return + * immediately.
    + * How quickly this function returns depends on run-time factors such as + * network status, print server configuration, and printer driver + * implementation-factors that are difficult to predict when writing an + * application. Calling this function from a thread that manages interaction + * with the user interface could make the application appear to be + * unresponsive. + * + * When the ClosePrinter function returns, the handle hPrinter is invalid, + * regardless of whether the function has succeeded or failed. + * + * @param hPrinter + * A handle to the printer object to be closed. This handle is + * returned by the OpenPrinter or AddPrinter function. + * @return If the function succeeds, the return value is a nonzero value. If + * the function fails, the return value is zero. + * + * @see + * ClosePrinter function + */ + boolean ClosePrinter(HANDLE hPrinter); + /** * The FindFirstPrinterChangeNotification function creates a change * notification object and returns a handle to the object. You can then use @@ -256,8 +612,6 @@ * the change, and to reset the change notification object for use in the * next wait operation. * - * @see MSDN - * * @param hPrinter * [in] A handle to the printer or print server that you want to * monitor. Use the OpenPrinter or AddPrinter function to @@ -286,9 +640,13 @@ * change notification object associated with the specified printer * or print server. If the function fails, the return value is * INVALID_HANDLE_VALUE. - */ + * + * @see + * FindFirstPrinterChangeNotification function + */ HANDLE FindFirstPrinterChangeNotification( - // _In_ + // _In_ HANDLE hPrinter, int fdwFilter, int fdwOptions, // _In_opt_ LPVOID pPrinterNotifyOptions); @@ -306,8 +664,6 @@ * FindFirstPrinterChangeNotification function creates the change * notification object and specifies the set of changes to be monitored. * - * @see MSDN - * * @param hChange * [in] A handle to a change notification object associated with * a printer or print server. You obtain such a handle by calling @@ -355,9 +711,13 @@ * * @return If the function succeeds, the return value is a nonzero value. If * the function fails, the return value is zero. - */ + * + * @see + * FindClosePrinterChangeNotification function + */ boolean FindNextPrinterChangeNotification( - // _In_ + // _In_ HANDLE hChange, // _Out_opt_ DWORDByReference pdwChange, @@ -373,8 +733,6 @@ * associated with the change notification object will no longer be * monitored by that object. * - * @see MSDN - * * @param hChange * [in] A handle to the change notification object to be closed. * This is a handle created by calling the @@ -382,13 +740,57 @@ * * @return If the function succeeds, the return value is a nonzero value. If * the function fails, the return value is zero. - */ + * + * @see + * FindClosePrinterChangeNotification function + */ boolean FindClosePrinterChangeNotification( - // _In_ + // _In_ HANDLE hChange); + /** + * The EnumJobs function retrieves information about a specified set of + * print jobs for a specified printer. + * + * @param hPrinter + * A handle to the printer object whose print jobs the function + * enumerates. Use the OpenPrinter or AddPrinter function to + * retrieve a printer handle. + * @param FirstJob + * The zero-based position within the print queue of the first + * print job to enumerate. For example, a value of 0 specifies + * that enumeration should begin at the first print job in the + * print queue; a value of 9 specifies that enumeration should + * begin at the tenth print job in the print queue. + * @param NoJobs + * The total number of print jobs to enumerate. + * @param Level + * The type of information returned in the pJob buffer. + * @param pJob + * A pointer to a buffer that receives an array of JOB_INFO_1, + * JOB_INFO_2, or JOB_INFO_3 structures. The buffer must be large + * enough to receive the array of structures and any strings or + * other data to which the structure members point. + * @param cbBuf + * The size, in bytes, of the pJob buffer. + * @param pcbNeeded + * A pointer to a variable that receives the number of bytes + * copied if the function succeeds. If the function fails, the + * variable receives the number of bytes required. + * @param pcReturned + * A pointer to a variable that receives the number of + * JOB_INFO_1, JOB_INFO_2, or JOB_INFO_3 structures returned in + * the pJob buffer. + * @return If the function succeeds, the return value is a nonzero value. If + * the function fails, the return value is zero. + * + * @see + * EnumJobs function + */ boolean EnumJobs( - // _In_ + // _In_ HANDLE hPrinter, // _In_ int FirstJob, @@ -405,33 +807,108 @@ // _Out_ IntByReference pcReturned); - public static class JOB_INFO_1 extends Structure { - public int JobId; - public String pPrinterName; - public String pMachineName; - public String pUserName; - public String pDocument; - public String pDatatype; - public String pStatus; - public int Status; - public int Priority; - public int Position; - public int TotalPages; - public int PagesPrinted; - public SYSTEMTIME Submitted; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "JobId", "pPrinterName", - "pMachineName", "pUserName", "pDocument", "pDatatype", - "pStatus", "Status", "Priority", "Position", "TotalPages", - "PagesPrinted", "Submitted" }); - } + /** + * The JOB_INFO_1 structure specifies print-job information such as the + * job-identifier value, the name of the printer for which the job is + * spooled, the name of the machine that created the print job, the name of + * the user that owns the print job, and so on. + * + * @see + * JOB_INFO_1 structure + */ + public static class JOB_INFO_1 extends Structure { + + public static final List FIELDS = createFieldsOrder( + "JobId", "pPrinterName", + "pMachineName", "pUserName", "pDocument", "pDatatype", + "pStatus", "Status", "Priority", "Position", "TotalPages", + "PagesPrinted", "Submitted"); + + /** + * A job identifier. + */ + public int JobId; + /** + * A pointer to a null-terminated string that specifies the name of the + * printer for which the job is spooled. + */ + public String pPrinterName; + /** + * A pointer to a null-terminated string that specifies the name of the + * machine that created the print job. + */ + public String pMachineName; + /** + * A pointer to a null-terminated string that specifies the name of the + * user that owns the print job. + */ + public String pUserName; + /** + * A pointer to a null-terminated string that specifies the name of the + * print job (for example, "MS-WORD: Review.doc"). + */ + public String pDocument; + /** + * A pointer to a null-terminated string that specifies the type of data + * used to record the print job. + */ + public String pDatatype; + /** + * A pointer to a null-terminated string that specifies the status of + * the print job. This member should be checked prior to Status and, if + * pStatus is NULL, the status is defined by the contents of the Status + * member. + */ + public String pStatus; + /** + * The job status. The value of this member can be zero or a combination + * of one or more of the following values. A value of zero indicates + * that the print queue was paused after the document finished spooling. + */ + public int Status; + /** + * The job priority. This member can be one of the following values or + * in the range between 1 through 99 (MIN_PRIORITY through + * MAX_PRIORITY). + */ + public int Priority; + /** + * The job's position in the print queue. + */ + public int Position; + /** + * The total number of pages that the document contains. This value may + * be zero if the print job does not contain page delimiting + * information. + */ + public int TotalPages; + /** + * The number of pages that have printed. This value may be zero if the + * print job does not contain page delimiting information. + */ + public int PagesPrinted; + /** + * A SYSTEMTIME structure that specifies the time that this document was + * spooled. + *

    + * This time value is in Universal Time Coordinate (UTC) format. You + * should convert it to a local time value before displaying it. You can + * use the FileTimeToLocalFileTime function to perform the conversion. + */ + public SYSTEMTIME Submitted; public JOB_INFO_1() { + super(); } public JOB_INFO_1(int size) { super(new Memory(size)); } + + @Override + protected List getFieldOrder() { + return FIELDS; + } } } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/WinspoolUtil.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/WinspoolUtil.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/WinspoolUtil.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/WinspoolUtil.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,27 +1,39 @@ /* Copyright (c) 2010 Daniel Doubrovkine, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.platform.win32.WinNT.HANDLEByReference; import com.sun.jna.platform.win32.Winspool.JOB_INFO_1; import com.sun.jna.platform.win32.Winspool.PRINTER_INFO_1; +import com.sun.jna.platform.win32.Winspool.PRINTER_INFO_2; import com.sun.jna.platform.win32.Winspool.PRINTER_INFO_4; import com.sun.jna.ptr.IntByReference; /** * Winspool Utility API. * - * @author dblock[at]dblock.org + * @author dblock[at]dblock.org, Ivan Ridao Freitas, Padrus */ public abstract class WinspoolUtil { @@ -45,6 +57,78 @@ return (PRINTER_INFO_1[]) pPrinterEnum.toArray(pcReturned.getValue()); } + + public static PRINTER_INFO_2[] getPrinterInfo2() { + return getPrinterInfo2(Winspool.PRINTER_ENUM_LOCAL); + } + + /** + * Returns printers that are physically attached to the local machine as + * well as remote printers to which it has a network connection. + */ + public static PRINTER_INFO_2[] getAllPrinterInfo2() { + // When Name is NULL, setting Flags to PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS + // enumerates printers that are installed on the local machine. + // These printers include those that are physically attached to the local machine + // as well as remote printers to which it has a network connection. + // See https://msdn.microsoft.com/en-us/library/windows/desktop/dd162692(v=vs.85).aspx + return getPrinterInfo2(Winspool.PRINTER_ENUM_LOCAL | Winspool.PRINTER_ENUM_CONNECTIONS); + } + + private static PRINTER_INFO_2[] getPrinterInfo2(int flags) { + IntByReference pcbNeeded = new IntByReference(); + IntByReference pcReturned = new IntByReference(); + Winspool.INSTANCE.EnumPrinters(flags, null, 2, null, 0, pcbNeeded, pcReturned); + if (pcbNeeded.getValue() <= 0) + return new PRINTER_INFO_2[0]; + + PRINTER_INFO_2 pPrinterEnum = new PRINTER_INFO_2(pcbNeeded.getValue()); + if (!Winspool.INSTANCE.EnumPrinters(flags, null, 2, pPrinterEnum.getPointer(), pcbNeeded.getValue(), pcbNeeded, + pcReturned)) + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + + pPrinterEnum.read(); + return (PRINTER_INFO_2[]) pPrinterEnum.toArray(pcReturned.getValue()); + } + + public static PRINTER_INFO_2 getPrinterInfo2(String printerName) { + IntByReference pcbNeeded = new IntByReference(); + IntByReference pcReturned = new IntByReference(); + HANDLEByReference pHandle = new HANDLEByReference(); + + if (!Winspool.INSTANCE.OpenPrinter(printerName, pHandle, null)) + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + + Win32Exception we = null; + PRINTER_INFO_2 pinfo2 = null; + + try { + Winspool.INSTANCE.GetPrinter(pHandle.getValue(), 2, null, 0, pcbNeeded); + if (pcbNeeded.getValue() <= 0) + return new PRINTER_INFO_2(); + + pinfo2 = new PRINTER_INFO_2(pcbNeeded.getValue()); + if (!Winspool.INSTANCE.GetPrinter(pHandle.getValue(), 2, pinfo2.getPointer(), pcbNeeded.getValue(), pcReturned)) + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + + pinfo2.read(); + } catch (Win32Exception e) { + we = e; + } finally { + if (!Winspool.INSTANCE.ClosePrinter(pHandle.getValue())) { + Win32Exception ex = new Win32Exception(Kernel32.INSTANCE.GetLastError()); + if (we != null) { + ex.addSuppressed(we); + } + } + } + + if (we != null) { + throw we; + } + + return pinfo2; + } public static PRINTER_INFO_4[] getPrinterInfo4() { IntByReference pcbNeeded = new IntByReference(); diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Winsvc.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Winsvc.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Winsvc.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Winsvc.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,25 +1,36 @@ /* Copyright (c) 2010 EugineLev, 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * You can freely decide which license you want to apply to + * the project. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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 java.util.Arrays; import java.util.List; import com.sun.jna.Memory; +import com.sun.jna.Pointer; import com.sun.jna.Structure; import com.sun.jna.platform.win32.WinNT.HANDLE; -import com.sun.jna.win32.StdCallLibrary; +import com.sun.jna.win32.W32APITypeMapper; /** * This module defines the 32-Bit Windows types and constants that are defined @@ -28,42 +39,44 @@ * Microsoft Windows SDK 7.0A. * @author EugineLev */ -public interface Winsvc extends StdCallLibrary { +public interface Winsvc { /** * Contains status information for a service. The ControlService, EnumDependentServices, * EnumServicesStatus, and QueryServiceStatus functions use this structure. A service - * uses this structure in the SetServiceStatus function to report its current status + * uses this structure in the SetServiceStatus function to report its current status * to the service control manager. */ public static class SERVICE_STATUS extends Structure { - + public static final List FIELDS = createFieldsOrder( + "dwServiceType", "dwCurrentState", "dwControlsAccepted", "dwWin32ExitCode", "dwServiceSpecificExitCode", "dwCheckPoint", "dwWaitHint"); + /** - * dwServiceType - the type of service. This member can be one + * dwServiceType - the type of service. This member can be one * of the following values: - * SERVICE_KERNEL_DRIVER, SERVICE_FILE_SYSTEM_DRIVER, - * SERVICE_WIN32_OWN_PROCESS, SERVICE_WIN32_SHARE_PROCESS, + * SERVICE_KERNEL_DRIVER, SERVICE_FILE_SYSTEM_DRIVER, + * SERVICE_WIN32_OWN_PROCESS, SERVICE_WIN32_SHARE_PROCESS, - * If the service type is either SERVICE_WIN32_OWN_PROCESS or - * SERVICE_WIN32_SHARE_PROCESS, and the service is running in the - * context of the LocalSystem account, the following type may also + * If the service type is either SERVICE_WIN32_OWN_PROCESS or + * SERVICE_WIN32_SHARE_PROCESS, and the service is running in the + * context of the LocalSystem account, the following type may also * be specified: * SERVICE_INTERACTIVE_PROCESS - * + * * These values can be found in WinNT.h */ public int dwServiceType; - + /** - * dwCurrentState - The current state of the service. + * dwCurrentState - The current state of the service. * This member can be one of the following values: * SERVICE_STOPPED, SERVICE_START_PENDING, SERVICE_STOP_PENDING, SERVICE_RUNNING, - * SERVICE_CONTINUE_PENDING, SERVICE_PAUSE_PENDING, SERVICE_PAUSED + * SERVICE_CONTINUE_PENDING, SERVICE_PAUSE_PENDING, SERVICE_PAUSED */ public int dwCurrentState; - + /** - * dwControlsAccepted - The control codes the service accepts and processes + * dwControlsAccepted - The control codes the service accepts and processes * in its handler function: * SERVICE_ACCEPT_STOP, SERVICE_ACCEPT_PAUSE_CONTINUE, SERVICE_ACCEPT_SHUTDOWN, * SERVICE_ACCEPT_PARAMCHANGE, SERVICE_ACCEPT_NETBINDCHANGE, SERVICE_ACCEPT_HARDWAREPROFILECHANGE, @@ -71,77 +84,82 @@ * SERVICE_ACCEPT_TIMECHANGE, SERVICE_ACCEPT_TRIGGEREVENT */ public int dwControlsAccepted; - + /** - * dwWin32ExitCode - The error code the service uses to report an error that occurs + * dwWin32ExitCode - The error code the service uses to report an error that occurs * when it is starting or stopping. To return an error code specific to the service, * the service must set this value to ERROR_SERVICE_SPECIFIC_ERROR to indicate that * the dwServiceSpecificExitCode member contains the error code. The service should * set this value to NO_ERROR when it is running and on normal termination. */ public int dwWin32ExitCode; - + /** * dwServiceSpecificExitCode - A service-specific error code that the service returns * when an error occurs while the service is starting or stopping. This value is * ignored unless the dwWin32ExitCode member is set to ERROR_SERVICE_SPECIFIC_ERROR. */ public int dwServiceSpecificExitCode; - + /** * dwCheckPoint - The check-point value the service increments periodically to report * its progress during a lengthy start, stop, pause, or continue operation. */ public int dwCheckPoint; - + /** - * dwWaitHint - The estimated time required for a pending start, stop, pause, or continue + * dwWaitHint - The estimated time required for a pending start, stop, pause, or continue * operation, in milliseconds. */ public int dwWaitHint; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "dwServiceType", "dwCurrentState", "dwControlsAccepted", "dwWin32ExitCode", "dwServiceSpecificExitCode", "dwCheckPoint", "dwWaitHint" }); - } - public SERVICE_STATUS() { super(); } + @Override + protected List getFieldOrder() { + return FIELDS; + } } /** - * Contains process status information for a service. The ControlServiceEx, + * Contains process status information for a service. The ControlServiceEx, * EnumServicesStatusEx, NotifyServiceStatusChange, and QueryServiceStatusEx * functions use this structure. */ public class SERVICE_STATUS_PROCESS extends Structure { + public static final List FIELDS = createFieldsOrder( + "dwServiceType", "dwCurrentState", "dwControlsAccepted", + "dwWin32ExitCode", "dwServiceSpecificExitCode", + "dwCheckPoint", "dwWaitHint", "dwProcessId", "dwServiceFlags"); + /** - * dwServiceType - the type of service. This member can be one + * dwServiceType - the type of service. This member can be one * of the following values: - * SERVICE_KERNEL_DRIVER, SERVICE_FILE_SYSTEM_DRIVER, - * SERVICE_WIN32_OWN_PROCESS, SERVICE_WIN32_SHARE_PROCESS, + * SERVICE_KERNEL_DRIVER, SERVICE_FILE_SYSTEM_DRIVER, + * SERVICE_WIN32_OWN_PROCESS, SERVICE_WIN32_SHARE_PROCESS, - * If the service type is either SERVICE_WIN32_OWN_PROCESS or - * SERVICE_WIN32_SHARE_PROCESS, and the service is running in the - * context of the LocalSystem account, the following type may also + * If the service type is either SERVICE_WIN32_OWN_PROCESS or + * SERVICE_WIN32_SHARE_PROCESS, and the service is running in the + * context of the LocalSystem account, the following type may also * be specified: * SERVICE_INTERACTIVE_PROCESS - * + * * These values can be found in WinNT.h */ public int dwServiceType; - + /** - * dwCurrentState - The current state of the service. + * dwCurrentState - The current state of the service. * This member can be one of the following values: * SERVICE_STOPPED, SERVICE_START_PENDING, SERVICE_STOP_PENDING, SERVICE_RUNNING, - * SERVICE_CONTINUE_PENDING, SERVICE_PAUSE_PENDING, SERVICE_PAUSED + * SERVICE_CONTINUE_PENDING, SERVICE_PAUSE_PENDING, SERVICE_PAUSED */ public int dwCurrentState; - + /** - * dwControlsAccepted - The control codes the service accepts and processes + * dwControlsAccepted - The control codes the service accepts and processes * in its handler function: * SERVICE_ACCEPT_STOP, SERVICE_ACCEPT_PAUSE_CONTINUE, SERVICE_ACCEPT_SHUTDOWN, * SERVICE_ACCEPT_PARAMCHANGE, SERVICE_ACCEPT_NETBINDCHANGE, SERVICE_ACCEPT_HARDWAREPROFILECHANGE, @@ -149,64 +167,199 @@ * SERVICE_ACCEPT_TIMECHANGE, SERVICE_ACCEPT_TRIGGEREVENT */ public int dwControlsAccepted; - + /** - * dwWin32ExitCode - The error code the service uses to report an error that occurs + * dwWin32ExitCode - The error code the service uses to report an error that occurs * when it is starting or stopping. To return an error code specific to the service, * the service must set this value to ERROR_SERVICE_SPECIFIC_ERROR to indicate that * the dwServiceSpecificExitCode member contains the error code. The service should * set this value to NO_ERROR when it is running and on normal termination. */ public int dwWin32ExitCode; - + /** * dwServiceSpecificExitCode - A service-specific error code that the service returns * when an error occurs while the service is starting or stopping. This value is * ignored unless the dwWin32ExitCode member is set to ERROR_SERVICE_SPECIFIC_ERROR. */ public int dwServiceSpecificExitCode; - + /** * dwCheckPoint - The check-point value the service increments periodically to report * its progress during a lengthy start, stop, pause, or continue operation. */ public int dwCheckPoint; - + /** - * dwWaitHint - The estimated time required for a pending start, stop, pause, or continue + * dwWaitHint - The estimated time required for a pending start, stop, pause, or continue * operation, in milliseconds. */ public int dwWaitHint; - + /** * dwProcessId - The process identifier of the service. */ public int dwProcessId; - + /** * This member can be one of the following values: 0, or SERVICE_RUNS_IN_SYSTEM_PROCESS */ public int dwServiceFlags; - - protected List getFieldOrder() { - return Arrays.asList(new String[] { "dwServiceType", "dwCurrentState", "dwControlsAccepted", "dwWin32ExitCode", "dwServiceSpecificExitCode", "dwCheckPoint", "dwWaitHint", "dwProcessId", "dwServiceFlags" }); - } - + public SERVICE_STATUS_PROCESS() { + super(); } - + public SERVICE_STATUS_PROCESS(int size) { super(new Memory(size)); } + + @Override + protected List getFieldOrder() { + return FIELDS; + } } + public abstract class ChangeServiceConfig2Info extends Structure { + public ChangeServiceConfig2Info() { + super(Boolean.getBoolean("w32.ascii") ? W32APITypeMapper.ASCII : W32APITypeMapper.UNICODE); + } + + public ChangeServiceConfig2Info(Pointer p) { + super(p, ALIGN_DEFAULT, Boolean.getBoolean("w32.ascii") ? W32APITypeMapper.ASCII : W32APITypeMapper.UNICODE); + } + } + + /** + * Represents the action the service controller should take on each failure of a service. A + * service is considered failed when it terminates without reporting a status of SERVICE_STOPPED + * to the service controller. + * To configure additional circumstances under which the failure actions are to be executed, see + * SERVICE_FAILURE_ACTIONS_FLAG. + */ + public class SERVICE_FAILURE_ACTIONS extends ChangeServiceConfig2Info { + public static class ByReference extends SERVICE_FAILURE_ACTIONS implements Structure.ByReference {} + + /** + * The time after which to reset the failure count to zero if there are no failures, in + * seconds. Specify INFINITE to indicate that this value should never be reset. + */ + public int dwResetPeriod; + /** + * The message to be broadcast to server users before rebooting in response to the + * SC_ACTION_REBOOT service controller action. + * If this value is NULL, the reboot message is unchanged. If the value is an empty string + * (""), the reboot message is deleted and no message is broadcast. + * This member can specify a localized string using the following format: + * "@[path]dllname,-strID" + * The string with identifier strID is loaded from dllname; the path is optional. For more + * information, see RegLoadMUIString. + * Windows Server 2003 and Windows XP: Localized strings are not supported until Windows + * Vista. + */ + public String lpRebootMsg; + /** + * The command line of the process for the CreateProcess function to execute in response to + * the SC_ACTION_RUN_COMMAND service controller action. This process runs under the same + * account as the service. + * If this value is NULL, the command is unchanged. If the value is an empty string (""), + * the command is deleted and no program is run when the service fails. + */ + public String lpCommand; + /** + * The number of elements in the lpsaActions array. + * If this value is 0, but lpsaActions is not NULL, the reset period and array of failure + * actions are deleted. + */ + public int cActions; + /** + * A pointer to an array of SC_ACTION structures. + * If this value is NULL, the cActions and dwResetPeriod members are ignored. + */ + public SC_ACTION.ByReference lpsaActions; + + public SERVICE_FAILURE_ACTIONS() { + super(); + } + + public SERVICE_FAILURE_ACTIONS(Pointer p) { + super(p); + read(); + } + + public static final List FIELDS = createFieldsOrder("dwResetPeriod", "lpRebootMsg", "lpCommand", "cActions", "lpsaActions"); + + @Override + protected List getFieldOrder() { + return FIELDS; + } + } + + /** + * Represents an action that the service control manager can perform. + */ + public class SC_ACTION extends Structure { + public static class ByReference extends SC_ACTION implements Structure.ByReference {} + /** + * The action to be performed. This member can be one of the following values from the + * SC_ACTION_TYPE enumeration type. + */ + public int type; + /** + * The time to wait before performing the specified action, in milliseconds. + */ + public int delay; + + public static final List FIELDS = createFieldsOrder("type", "delay"); + + @Override + protected List getFieldOrder() { + return FIELDS; + } + } + + /** + * Contains the failure actions flag setting of a service. This setting determines when failure + * actions are to be executed. + */ + public class SERVICE_FAILURE_ACTIONS_FLAG extends ChangeServiceConfig2Info { + /** + * If this member is TRUE and the service has configured failure actions, the failure + * actions are queued if the service process terminates without reporting a status of + * SERVICE_STOPPED or if it enters the SERVICE_STOPPED state but the dwWin32ExitCode member + * of the SERVICE_STATUS structure is not ERROR_SUCCESS (0). + * If this member is FALSE and the service has configured failure actions, the failure + * actions are queued only if the service terminates without reporting a status of + * SERVICE_STOPPED. + * This setting is ignored unless the service has configured failure actions. For + * information on configuring failure actions, see ChangeServiceConfig2. + */ + public int fFailureActionsOnNonCrashFailures; + + public static final List FIELDS = createFieldsOrder("fFailureActionsOnNonCrashFailures"); + + @Override + protected List getFieldOrder() { + return FIELDS; + } + + public SERVICE_FAILURE_ACTIONS_FLAG() { + super(); + } + + public SERVICE_FAILURE_ACTIONS_FLAG(Pointer p) { + super(p); + read(); + } + } + // // Service flags for QueryServiceStatusEx // int SERVICE_RUNS_IN_SYSTEM_PROCESS = 0x00000001; - + public static class SC_HANDLE extends HANDLE { } - + // // Service Control Manager object specific access types // @@ -217,10 +370,10 @@ int SC_MANAGER_QUERY_LOCK_STATUS = 0x0010; int SC_MANAGER_MODIFY_BOOT_CONFIG = 0x0020; - int SC_MANAGER_ALL_ACCESS = - WinNT.STANDARD_RIGHTS_REQUIRED | SC_MANAGER_CONNECT - | SC_MANAGER_CREATE_SERVICE | SC_MANAGER_ENUMERATE_SERVICE - | SC_MANAGER_LOCK | SC_MANAGER_QUERY_LOCK_STATUS + int SC_MANAGER_ALL_ACCESS = + WinNT.STANDARD_RIGHTS_REQUIRED | SC_MANAGER_CONNECT + | SC_MANAGER_CREATE_SERVICE | SC_MANAGER_ENUMERATE_SERVICE + | SC_MANAGER_LOCK | SC_MANAGER_QUERY_LOCK_STATUS | SC_MANAGER_MODIFY_BOOT_CONFIG; // @@ -237,33 +390,34 @@ int SERVICE_USER_DEFINED_CONTROL = 0x0100; int SERVICE_ALL_ACCESS = - WinNT.STANDARD_RIGHTS_REQUIRED | SERVICE_QUERY_CONFIG - | SERVICE_CHANGE_CONFIG | SERVICE_QUERY_STATUS - | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_START | SERVICE_STOP - | SERVICE_PAUSE_CONTINUE | SERVICE_INTERROGATE + WinNT.STANDARD_RIGHTS_REQUIRED | SERVICE_QUERY_CONFIG + | SERVICE_CHANGE_CONFIG | SERVICE_QUERY_STATUS + | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_START | SERVICE_STOP + | SERVICE_PAUSE_CONTINUE | SERVICE_INTERROGATE | SERVICE_USER_DEFINED_CONTROL; // // Controls // - int SERVICE_CONTROL_STOP = 0x00000001; - int SERVICE_CONTROL_PAUSE = 0x00000002; - int SERVICE_CONTROL_CONTINUE = 0x00000003; - int SERVICE_CONTROL_INTERROGATE = 0x00000004; - // int SERVICE_CONTROL_SHUTDOWN = 0x00000005; - int SERVICE_CONTROL_PARAMCHANGE = 0x00000006; - int SERVICE_CONTROL_NETBINDADD = 0x00000007; - int SERVICE_CONTROL_NETBINDREMOVE = 0x00000008; - int SERVICE_CONTROL_NETBINDENABLE = 0x00000009; - int SERVICE_CONTROL_NETBINDDISABLE = 0x0000000A; - // int SERVICE_CONTROL_DEVICEEVENT = 0x0000000B; - // int SERVICE_CONTROL_HARDWAREPROFILECHANGE = 0x0000000C; - // int SERVICE_CONTROL_POWEREVENT = 0x0000000D; - // int SERVICE_CONTROL_SESSIONCHANGE = 0x0000000E; - // int SERVICE_CONTROL_PRESHUTDOWN = 0x0000000F; - // int SERVICE_CONTROL_TIMECHANGE = 0x00000010; - // int SERVICE_CONTROL_TRIGGEREVENT = 0x00000020; - + int SERVICE_CONTROL_STOP = 0x00000001; + int SERVICE_CONTROL_PAUSE = 0x00000002; + int SERVICE_CONTROL_CONTINUE = 0x00000003; + int SERVICE_CONTROL_INTERROGATE = 0x00000004; + int SERVICE_CONTROL_SHUTDOWN = 0x00000005; + int SERVICE_CONTROL_PARAMCHANGE = 0x00000006; + int SERVICE_CONTROL_NETBINDADD = 0x00000007; + int SERVICE_CONTROL_NETBINDREMOVE = 0x00000008; + int SERVICE_CONTROL_NETBINDENABLE = 0x00000009; + int SERVICE_CONTROL_NETBINDDISABLE = 0x0000000A; + int SERVICE_CONTROL_DEVICEEVENT = 0x0000000B; + int SERVICE_CONTROL_HARDWAREPROFILECHANGE = 0x0000000C; + int SERVICE_CONTROL_POWEREVENT = 0x0000000D; + int SERVICE_CONTROL_SESSIONCHANGE = 0x0000000E; + int SERVICE_CONTROL_PRESHUTDOWN = 0x0000000F; + int SERVICE_CONTROL_TIMECHANGE = 0x00000010; + int SERVICE_CONTROL_TRIGGEREVENT = 0x00000020; + int SERVICE_CONTROL_USERMODEREBOOT = 0x00000040; + // // Service State -- for CurrentState // @@ -289,12 +443,33 @@ int SERVICE_ACCEPT_PRESHUTDOWN = 0x00000100; int SERVICE_ACCEPT_TIMECHANGE = 0x00000200; int SERVICE_ACCEPT_TRIGGEREVENT = 0x00000400; + + // + // ChangeServiceConfig2 dwInfoLevel values + // + int SERVICE_CONFIG_DESCRIPTION = 0x00000001; + int SERVICE_CONFIG_FAILURE_ACTIONS = 0x00000002; + int SERVICE_CONFIG_DELAYED_AUTO_START_INFO = 0x00000003; + int SERVICE_CONFIG_FAILURE_ACTIONS_FLAG = 0x00000004; + int SERVICE_CONFIG_SERVICE_SID_INFO = 0x00000005; + int SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO = 0x00000006; + int SERVICE_CONFIG_PRESHUTDOWN_INFO = 0x00000007; + int SERVICE_CONFIG_TRIGGER_INFO = 0x00000008; + int SERVICE_CONFIG_PREFERRED_NODE = 0x00000009; + int SERVICE_CONFIG_LAUNCH_PROTECTED = 0x0000000c; + + // + // Service failure actions + // + int SC_ACTION_NONE = 0x00000000; + int SC_ACTION_RESTART = 0x00000001; + int SC_ACTION_REBOOT = 0x00000002; + int SC_ACTION_RUN_COMMAND = 0x00000003; /** - * The SC_STATUS_TYPE enumeration type contains values + * The SC_STATUS_TYPE enumeration type contains values */ - public abstract class SC_STATUS_TYPE { + public abstract class SC_STATUS_TYPE { public static final int SC_STATUS_PROCESS_INFO = 0; } - } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/WinUser.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/WinUser.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/WinUser.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/WinUser.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2010 Daniel Doubrovkine, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the GNU - * Lesser General Public License for more details. + * 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; @@ -19,10 +30,10 @@ import com.sun.jna.Pointer; import com.sun.jna.Structure; import com.sun.jna.Union; -import com.sun.jna.WString; import com.sun.jna.platform.win32.BaseTSD.ULONG_PTR; import com.sun.jna.platform.win32.WinNT.HANDLE; -import com.sun.jna.win32.StdCallLibrary; +import com.sun.jna.win32.StdCallLibrary.StdCallCallback; +import com.sun.jna.win32.W32APITypeMapper; /** * Ported from WinUser.h Microsoft Windows SDK 6.0A. @@ -30,7 +41,7 @@ * @author dblock[at]dblock.org * @author Andreas "PAX" Lück, onkelpax-git[at]yahoo.de */ -public interface WinUser extends StdCallLibrary, WinDef { +public interface WinUser extends WinDef { HWND HWND_BROADCAST = new HWND(Pointer.createConstant(0xFFFF)); HWND HWND_MESSAGE = new HWND(Pointer.createConstant(-3)); @@ -366,6 +377,58 @@ LRESULT callback(int nCode, WPARAM wParam, KBDLLHOOKSTRUCT lParam); } + /** + * An application-defined callback (or hook) function that the system calls + * in response to events generated by an accessible object.
    + * The hook function processes the event notifications as required.
    + * Clients install the hook function and request specific types of event + * notifications by calling SetWinEventHook.
    + * The WINEVENTPROC type defines a pointer to this callback function. + * WinEventProc is a placeholder for the application-defined function name. + */ + public static interface WinEventProc extends Callback { + /** + * @param hWinEventHook + * Type: HWINEVENTHOOK
    + * Handle to an event hook function.
    + * This value is returned by SetWinEventHook when the hook + * function is installed and is specific to each instance of + * the hook function. + * @param event + * Type: DWORD
    + * Specifies the event that occurred.
    + * This value is one of the event constants. + * @param hwnd + * Type: HWND
    + * Handle to the window that generates the event, or NULL if + * no window is associated with the event.
    + * For example, the mouse pointer is not associated with a + * window. + * @param idObject + * Type: LONG
    + * Identifies the object associated with the event.
    + * This is one of the object identifiers or a custom object + * ID. + * @param idChild + * Type: LONG
    + * Identifies whether the event was triggered by an object or + * a child element of the object.
    + * If this value is CHILDID_SELF, the event was triggered by + * the object; otherwise, this value is the child ID of the + * element that triggered the event. + * @param dwEventThread + * Type: DWORD
    + * Identifies the thread that generated the event, or the + * thread that owns the current window. + * @param dwmsEventTime + * Type: DWORD
    + * Specifies the time, in milliseconds, that the event was + * generated. + */ + void callback(HANDLE hWinEventHook, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread, + DWORD dwmsEventTime); + } + /** Specifies the width and height of a rectangle. */ public class SIZE extends Structure { public int cx, cy; @@ -390,6 +453,8 @@ int AC_SRC_NO_ALPHA = 0x02; public class BLENDFUNCTION extends Structure { + public static final List FIELDS = createFieldsOrder("BlendOp", "BlendFlags", "SourceConstantAlpha", "AlphaFormat"); + public byte BlendOp = AC_SRC_OVER; // only valid value public byte BlendFlags = 0; // only valid value public byte SourceConstantAlpha; @@ -397,8 +462,7 @@ @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "BlendOp", "BlendFlags", - "SourceConstantAlpha", "AlphaFormat" }); + return FIELDS; } } @@ -490,6 +554,12 @@ * associated with the thread that registered the hot key. */ int WM_HOTKEY = 0x0312; + + /** + * Used to define private messages for use by private window classes, + * usually of the form WM_USER+x, where x is an integer value. + */ + int WM_USER = 0x0400; int WM_KEYUP = 257; int WM_SYSKEYDOWN = 260; @@ -751,6 +821,125 @@ int SC_MAXIMIZE = 0xF030; /** + * Creates a push button that posts a WM_COMMAND message to the owner window + * when the user selects the button. + */ + int BS_PUSHBUTTON = 0x00000000; + + /** + * Creates a push button that behaves like a BS_PUSHBUTTON style button, but + * has a distinct appearance.
    + * If the button is in a dialog box, the user can select the button by + * pressing the ENTER key, even when the button does not have the input + * focus.
    + * This style is useful for enabling the user to quickly select the most + * likely (default) option. + */ + int BS_DEFPUSHBUTTON = 0x00000001; + + /** + * Creates a small, empty check box with text. By default, the text is + * displayed to the right of the check box.
    + * To display the text to the left of the check box, combine this flag with + * the BS_LEFTTEXT style (or with the equivalent BS_RIGHTBUTTON style). + */ + int BS_CHECKBOX = 0x00000002; + + /** + * Creates a button that is the same as a check box, except that the check + * state automatically toggles between checked and cleared each time the + * user selects the check box. + */ + int BS_AUTOCHECKBOX = 0x00000003; + + /** + * Creates a small circle with text. By default, the text is displayed to + * the right of the circle.
    + * To display the text to the left of the circle, combine this flag with the + * BS_LEFTTEXT style (or with the equivalent BS_RIGHTBUTTON style).
    + * Use radio buttons for groups of related, but mutually exclusive choices. + */ + int BS_RADIOBUTTON = 0x00000004; + + /** + * Creates a button that is the same as a check box, except that the box can + * be grayed as well as checked or cleared.
    + * Use the grayed state to show that the state of the check box is not + * determined. + */ + int BS_3STATE = 0x00000005; + + /** + * Creates a button that is the same as a three-state check box, except that + * the box changes its state when the user selects it.
    + * The state cycles through checked, indeterminate, and cleared. + */ + int BS_AUTO3STATE = 0x00000006; + + /** + * Creates a rectangle in which other controls can be grouped. Any text + * associated with this style is displayed in the rectangle's upper left + * corner. + */ + int BS_GROUPBOX = 0x00000007; + + /** + * Obsolete, but provided for compatibility with 16-bit versions of Windows. + * Applications should use BS_OWNERDRAW instead. + */ + int BS_USERBUTTON = 0x00000008; + + /** + * Creates a button that is the same as a radio button, except that when the + * user selects it,
    + * the system automatically sets the button's check state to checked and + * automatically sets the check state for all other buttons in the same + * group to cleared. + */ + int BS_AUTORADIOBUTTON = 0x00000009; + + /** + * A button that only shows the text + */ + int BS_PUSHBOX = 0x0000000A; + + /** + * Creates an owner-drawn button.
    + * The owner window receives a WM_DRAWITEM message when a visual aspect of + * the button has changed.
    + * Do not combine the BS_OWNERDRAW style with any other button styles. + */ + int BS_OWNERDRAW = 0x0000000B; + + /** + * Do not use this style.
    + * A composite style bit that results from using the OR operator on BS_* + * style bits.
    + * It can be used to mask out valid BS_* bits from a given bitmask.
    + * Note that this is out of date and does not correctly include all valid + * styles.
    + * Thus, you should not use this style.
    + *
    + * However, it makes basic GetWindowLong work when trying to test for a + * button style for basic button controls. + */ + int BS_TYPEMASK = 0x0000000F; + + /** + * Places text on the left side of the radio button or check box when + * combined with a radio button or check box style. Same as the + * BS_RIGHTBUTTON style. + */ + int BS_LEFTTEXT = 0x00000020; + + /** + * Used by User32.SetWindowPos.
    + * Prevents the window from receiving the WM_WINDOWPOSCHANGING message. + */ + int SWP_NOSENDCHANGING = 0x0400; + + + /** * Contains information about a simulated message generated by an input * device other than a keyboard or mouse. */ @@ -995,6 +1184,7 @@ * Instantiates a new wndclassex. */ public WNDCLASSEX() { + super(W32APITypeMapper.DEFAULT); } /** @@ -1004,7 +1194,7 @@ * the memory */ public WNDCLASSEX(Pointer memory) { - super(memory); + super(memory, Structure.ALIGN_DEFAULT, W32APITypeMapper.DEFAULT); read(); } @@ -1039,7 +1229,7 @@ public String lpszMenuName; /** The lpsz class name. */ - public WString lpszClassName; + public String lpszClassName; /** The h icon sm. */ public HICON hIconSm; @@ -1059,7 +1249,7 @@ * * WindowProc is a placeholder for the application-defined function name. */ - public interface WindowProc extends Callback { + public interface WindowProc extends StdCallCallback { /** * @param hwnd @@ -1144,12 +1334,12 @@ /** *

    The MONITORINFO structure contains information about a display monitor.

    - * The {@link User32#GetMonitorInfo} function stores + * The {@link User32#GetMonitorInfo} function stores * information into a MONITORINFO structure

    - * The MONITORINFO structure is a subset of the MONITORINFOEX structure. + * The MONITORINFO structure is a subset of the MONITORINFOEX structure. */ - public class MONITORINFO extends Structure - { + public class MONITORINFO extends Structure { + public static final List FIELDS = createFieldsOrder("cbSize", "rcMonitor", "rcWork", "dwFlags"); /** * The size, in bytes, of the structure. */ @@ -1179,21 +1369,20 @@ public int dwFlags; @Override - protected List getFieldOrder() - { - return Arrays.asList("cbSize", "rcMonitor", "rcWork", "dwFlags"); + protected List getFieldOrder() { + return FIELDS; } } /** *

    The MONITORINFOEX structure contains information about a display monitor.

    - * The {@link User32#GetMonitorInfo} function stores + * The {@link User32#GetMonitorInfo} function stores * information into a MONITORINFOEX structure

    - * The MONITORINFOEX structure is a superset of the MONITORINFO structure. - * The MONITORINFOEX structure adds a string member to contain a name for the display monitor. + * The MONITORINFOEX structure is a superset of the MONITORINFO structure. + * The MONITORINFOEX structure adds a string member to contain a name for the display monitor. */ - public class MONITORINFOEX extends Structure - { + public class MONITORINFOEX extends Structure { + public static final List FIELDS = createFieldsOrder("cbSize", "rcMonitor", "rcWork", "dwFlags", "szDevice"); /** * The size, in bytes, of the structure. */ @@ -1229,38 +1418,36 @@ */ public char[] szDevice; - public MONITORINFOEX() - { + public MONITORINFOEX() { szDevice = new char[CCHDEVICENAME]; cbSize = size(); } @Override - protected List getFieldOrder() - { - return Arrays.asList("cbSize", "rcMonitor", "rcWork", "dwFlags", "szDevice"); + protected List getFieldOrder() { + return FIELDS; } } /** * An application-defined callback function that is called by the {@link User32#EnumDisplayMonitors} function. *

    - * You can use the EnumDisplayMonitors function to enumerate the set of display monitors that intersect - * the visible region of a specified device context and, optionally, a clipping rectangle. To do this, + * You can use the EnumDisplayMonitors function to enumerate the set of display monitors that intersect + * the visible region of a specified device context and, optionally, a clipping rectangle. To do this, * set the hdc parameter to a non-NULL value, and set the lprcClip parameter as needed. *

    - * You can also use the EnumDisplayMonitors function to enumerate one or more of the display monitors on - * the desktop, without supplying a device context. To do this, set the hdc parameter of + * You can also use the EnumDisplayMonitors function to enumerate one or more of the display monitors on + * the desktop, without supplying a device context. To do this, set the hdc parameter of * EnumDisplayMonitors to NULL and set the lprcClip parameter as needed. *

    - * In all cases, EnumDisplayMonitors calls a specified MonitorEnumProc function once for each display - * monitor in the calculated enumeration set. The MonitorEnumProc function always receives a handle to - * the display monitor. If the hdc parameter of EnumDisplayMonitors is non-NULL, the MonitorEnumProc - * function also receives a handle to a device context whose color format is appropriate for the - * display monitor. You can then paint into the device context in a manner that is optimal for the + * In all cases, EnumDisplayMonitors calls a specified MonitorEnumProc function once for each display + * monitor in the calculated enumeration set. The MonitorEnumProc function always receives a handle to + * the display monitor. If the hdc parameter of EnumDisplayMonitors is non-NULL, the MonitorEnumProc + * function also receives a handle to a device context whose color format is appropriate for the + * display monitor. You can then paint into the device context in a manner that is optimal for the * display monitor. */ - public interface MONITORENUMPROC extends Callback + public interface MONITORENUMPROC extends StdCallCallback { /** * @param hMonitor A handle to the display monitor. This value will always be non-NULL. @@ -1323,6 +1510,28 @@ * message within the timeout interval. For more information, see {@link com.sun.jna.platform.win32.User32#ExitWindowsEx}. */ int EWX_FORCEIFHUNG = 0x00000010; + /* GetAncestor properties */ + /** + * Retrieves the parent window. This does not include the owner, as it does with the GetParent function. + * + * @see MSDN + */ + int GA_PARENT = 1; + + /** + * Retrieves the root window by walking the chain of parent windows. + * + * @see MSDN + */ + int GA_ROOT = 2; + + /** + * Retrieves the owned root window by walking the chain of parent and owner windows returned by GetParent. + * + * @see MSDN + */ + int GA_ROOTOWNER = 3; + /* GetClassLong properties */ /** * Retrieves an ATOM value that uniquely identifies the window class. This @@ -1331,6 +1540,20 @@ int GCW_ATOM = -32; /** + * Retrieves a handle to the icon associated with the class. + * + * @see MSDN + */ + int GCL_HICON = -14; + + /** + * Retrieves a handle to the small icon associated with the class. + * + * @see MSDN + */ + int GCL_HICONSM = -34; + + /** * Retrieves the size, in bytes, of the extra memory associated with the * class. */ @@ -1534,6 +1757,7 @@ * @see */ public class RAWINPUTDEVICELIST extends Structure { + public static final List FIELDS = createFieldsOrder("hDevice", "dwType"); public HANDLE hDevice; public int dwType; @@ -1551,7 +1775,7 @@ @Override protected List getFieldOrder() { - return Arrays.asList("hDevice", "dwType"); + return FIELDS; } @Override @@ -1559,4 +1783,173 @@ return "hDevice=" + hDevice + ", dwType=" + dwType; } } + + /** + * A handle to a bitmap (HBITMAP). + */ + public int CF_BITMAT = 2; + /** + * A memory object containing a BITMAPINFO structure followed by the bitmap + * bits. + */ + public int CF_DIB = 8; + /** + * A memory object containing a BITMAPV5HEADER structure followed by the + * bitmap color space information and the bitmap bits. + */ + public int CF_DIBV5 = 17; + /** + * Software Arts' Data Interchange Format. + */ + public int CF_DIF = 5; + /** + * Bitmap display format associated with a private format. The hMem + * parameter must be a handle to data that can be displayed in bitmap format + * in lieu of the privately formatted data. + */ + public int CF_DSPBITMAP = 0x0082; + /** + * Enhanced metafile display format associated with a private format. The + * hMem parameter must be a handle to data that can be displayed in enhanced + * metafile format in lieu of the privately formatted data. + */ + public int CF_DSPENHMETAFILE = 0x008E; + /** + * Metafile-picture display format associated with a private format. The + * hMem parameter must be a handle to data that can be displayed in + * metafile-picture format in lieu of the privately formatted data. + */ + public int CF_DSPMETAFILEPICT = 0x0083; + /** + * Text display format associated with a private format. The hMem parameter + * must be a handle to data that can be displayed in text format in lieu of + * the privately formatted data. + */ + public int CF_DSPTEXT = 0x0081; + /** + * A handle to an enhanced metafile (HENHMETAFILE). + */ + public int CF_ENHMETAFILE = 14; + /** + * Start of a range of integer values for application-defined GDI object + * clipboard formats. The end of the range is CF_GDIOBJLAST. + * + *

    + * Handles associated with clipboard formats in this range are not + * automatically deleted using the GlobalFree function when the clipboard is + * emptied. Also, when using values in this range, the hMem parameter is not + * a handle to a GDI object, but is a handle allocated by the GlobalAlloc + * function with the GMEM_MOVEABLE flag.

    + */ + public int CF_GDIOBJFIRST = 0x0300; + /** + * @see WinUser#CF_GDIOBJFIRST + */ + public int CF_GDIOBJLAST = 0x03FF; + /** + * A handle to type HDROP that identifies a list of files. An application + * can retrieve information about the files by passing the handle to the + * DragQueryFile function. + */ + public int CF_HDROP = 15; + /** + * The data is a handle to the locale identifier associated with text in the + * clipboard. When you close the clipboard, if it contains CF_TEXT data but + * no CF_LOCALE data, the system automatically sets the CF_LOCALE format to + * the current input language. You can use the CF_LOCALE format to associate + * a different locale with the clipboard text. + * + *

    + * An application that pastes text from the clipboard can retrieve this + * format to determine which character set was used to generate the + * text.

    + *

    + * Note that the clipboard does not support plain text in multiple character + * sets. To achieve this, use a formatted text data type such as RTF + * instead.

    + *

    + * The system uses the code page associated with CF_LOCALE to implicitly + * convert from CF_TEXT to CF_UNICODETEXT. Therefore, the correct code page + * table is used for the conversion.

    + */ + public int CF_LOCALE = 16; + /** + * Handle to a metafile picture format as defined by the METAFILEPICT + * structure. When passing a CF_METAFILEPICT handle by means of DDE, the + * application responsible for deleting hMem should also free the metafile + * referred to by the CF_METAFILEPICT handle. + */ + public int CF_METAFILEPICT = 3; + /** + * Text format containing characters in the OEM character set. Each line + * ends with a carriage return/linefeed (CR-LF) combination. A null + * character signals the end of the data. + */ + public int CF_OEMTEXT = 7; + /** + * Owner-display format. The clipboard owner must display and update the + * clipboard viewer window, and receive the WM_ASKCBFORMATNAME, + * WM_HSCROLLCLIPBOARD, WM_PAINTCLIPBOARD, WM_SIZECLIPBOARD, and + * WM_VSCROLLCLIPBOARD messages. The hMem parameter must be NULL. + */ + public int CF_OWNERDISPLAY = 0x0080; + /** + * Handle to a color palette. Whenever an application places data in the + * clipboard that depends on or assumes a color palette, it should place the + * palette on the clipboard as well. + * + *

    + * If the clipboard contains data in the CF_PALETTE (logical color palette) + * format, the application should use the SelectPalette and RealizePalette + * functions to realize (compare) any other data in the clipboard against + * that logical palette.

    + *

    + * When displaying clipboard data, the clipboard always uses as its current + * palette any object on the clipboard that is in the CF_PALETTE format.

    + */ + public int CF_PALETTE = 9; + /** + * Data for the pen extensions to the Microsoft Windows for Pen Computing. + */ + public int CF_PENDATA = 10; + /** + * Start of a range of integer values for private clipboard formats. The + * range ends with CF_PRIVATELAST. Handles associated with private clipboard + * formats are not freed automatically; the clipboard owner must free such + * handles, typically in response to the WM_DESTROYCLIPBOARD message. + */ + public int CF_PRIVATEFIRST = 0x0200; + /** + * @see WinUser#CF_PRIVATEFIRST + */ + public int CF_PRIVATELAST = 0x02FF; + /** + * Represents audio data more complex than can be represented in a CF_WAVE + * standard wave format. + */ + public int CF_RIFF = 11; + /** + * Microsoft Symbolic Link (SYLK) format. + */ + public int CF_SYLK = 4; + /** + * Text format. Each line ends with a carriage return/linefeed (CR-LF) + * combination. A null character signals the end of the data. Use this + * format for ANSI text. + */ + public int CF_TEXT = 1; + /** + * Tagged-image file format. + */ + public int CF_TIFF = 6; + /** + * Unicode text format. Each line ends with a carriage return/linefeed + * (CR-LF) combination. A null character signals the end of the data. + */ + public int CF_UNICODETEXT = 13; + /** + * Represents audio data in one of the standard wave formats, such as 11 kHz + * or 22 kHz PCM. + */ + public int CF_WAVE = 12; } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Wtsapi32.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Wtsapi32.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/Wtsapi32.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/Wtsapi32.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2012 Tobias Wolf, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; @@ -19,8 +30,7 @@ public interface Wtsapi32 extends StdCallLibrary { - Wtsapi32 INSTANCE = (Wtsapi32) Native.loadLibrary("Wtsapi32", - Wtsapi32.class, W32APIOptions.DEFAULT_OPTIONS); + Wtsapi32 INSTANCE = Native.loadLibrary("Wtsapi32", Wtsapi32.class, W32APIOptions.DEFAULT_OPTIONS); int NOTIFY_FOR_ALL_SESSIONS = 1; @@ -30,51 +40,51 @@ * The session identified by lParam was connected to the console terminal or * RemoteFX session. */ - public static final int WTS_CONSOLE_CONNECT = 0x1; + int WTS_CONSOLE_CONNECT = 0x1; /** * The session identified by lParam was disconnected from the console * terminal or RemoteFX session. */ - public static final int WTS_CONSOLE_DISCONNECT = 0x2; + int WTS_CONSOLE_DISCONNECT = 0x2; /** * The session identified by lParam was connected to the remote terminal. */ - public static final int WTS_REMOTE_CONNECT = 0x3; + int WTS_REMOTE_CONNECT = 0x3; /** * The session identified by lParam was disconnected from the remote * terminal. */ - public static final int WTS_REMOTE_DISCONNECT = 0x4; + int WTS_REMOTE_DISCONNECT = 0x4; /** * A user has logged on to the session identified by lParam. */ - public static final int WTS_SESSION_LOGON = 0x5; + int WTS_SESSION_LOGON = 0x5; /** * A user has logged off the session identified by lParam. */ - public static final int WTS_SESSION_LOGOFF = 0x6; + int WTS_SESSION_LOGOFF = 0x6; /** * The session identified by lParam has been locked. */ - public static final int WTS_SESSION_LOCK = 0x7; + int WTS_SESSION_LOCK = 0x7; /** * The session identified by lParam has been unlocked. */ - public static final int WTS_SESSION_UNLOCK = 0x8; + int WTS_SESSION_UNLOCK = 0x8; /** * The session identified by lParam has changed its remote controlled * status. To determine the status, call GetSystemMetrics and check the * SM_REMOTECONTROL metric. */ - public static final int WTS_SESSION_REMOTE_CONTROL = 0x9; + int WTS_SESSION_REMOTE_CONTROL = 0x9; /** * Registers the specified window to receive session change notifications. @@ -90,7 +100,7 @@ * @return If the function succeeds, the return value is TRUE. Otherwise, it * is FALSE. To get extended error information, call GetLastError. */ - public boolean WTSRegisterSessionNotification(HWND hWnd, int dwFlags); + boolean WTSRegisterSessionNotification(HWND hWnd, int dwFlags); /** * Unregisters the specified window so that it receives no further session @@ -103,5 +113,5 @@ * @return If the function succeeds, the return value is TRUE. Otherwise, it * is FALSE. To get extended error information, call GetLastError. */ - public boolean WTSUnRegisterSessionNotification(HWND hWnd); + boolean WTSUnRegisterSessionNotification(HWND hWnd); } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/WTypes.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/WTypes.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/win32/WTypes.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/win32/WTypes.java 2017-03-14 19:31:03.000000000 +0000 @@ -3,15 +3,26 @@ */ /* Copyright (c) 2010 Timothy Wall, All Rights Reserved - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; @@ -22,10 +33,11 @@ import com.sun.jna.Structure; import com.sun.jna.platform.win32.WinDef.USHORT; import com.sun.jna.ptr.ByReference; +import java.io.UnsupportedEncodingException; /** * Constant defined in WTypes.h - * + * * @author scott.palmer * @author Tobias Wolf, wolf.tobias@gmx.net */ @@ -61,13 +73,40 @@ public static int CLSCTX_ALL = CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER | CLSCTX_LOCAL_SERVER; + /** + * BSTR wrapper. + * + *

    From MSDN:

    + * + *
    A BSTR (Basic string or binary string) is a string data type + * that is used by COM, Automation, and Interop functions. Use the BSTR data + * type in all interfaces that will be accessed from script.
    + * + *

    The memory structure:

    + * + *
    + *
    Length prefix
    + *
    Length of the data array holding the string data and does not include + * the final two NULL characters.
    + *
    Data string
    + *
    UTF-16LE encoded bytes for the string.
    + *
    Terminator
    + *
    Two null characters
    + *
    + * + *

    The "value" of the BSTR is the pointer to the start of the Data String, + * the length prefix is the four bytes before that.

    + * + *

    The MSDN states, that a BSTR derived from a Nullpointer is treated + * as a string containing zero characters.

    + */ public static class BSTR extends PointerType { public static class ByReference extends BSTR implements Structure.ByReference { } public BSTR() { - super(new Memory(Pointer.SIZE)); + super(Pointer.NULL); } public BSTR(Pointer pointer) { @@ -75,21 +114,39 @@ } public BSTR(String value) { - super(new Memory((value.length() + 1L) * Native.WCHAR_SIZE)); + super(); this.setValue(value); } public void setValue(String value) { - this.getPointer().setWideString(0, value); + if(value == null) { + value = ""; + } + try { + byte[] encodedValue = value.getBytes("UTF-16LE"); + // 4 bytes for the length prefix, length for the encoded data, + // 2 bytes for the two NULL terminators + Memory mem = new Memory(4 + encodedValue.length + 2); + mem.clear(); + mem.setInt(0, encodedValue.length); + mem.write(4, encodedValue, 0, encodedValue.length); + this.setPointer(mem.share(4)); + } catch (UnsupportedEncodingException ex) { + throw new RuntimeException("UTF-16LE charset is not supported", ex); + } } public String getValue() { - Pointer pointer = this.getPointer(); - String str = null; - if (pointer != null) - str = pointer.getWideString(0); - - return str; + try { + Pointer pointer = this.getPointer(); + if(pointer == null) { + return ""; + } + int stringLength = pointer.getInt(-4); + return new String(pointer.getByteArray(0, stringLength), "UTF-16LE"); + } catch (UnsupportedEncodingException ex) { + throw new RuntimeException("UTF-16LE charset is not supported", ex); + } } @Override @@ -196,7 +253,7 @@ } public static class LPOLESTR extends PointerType { - public static class ByReference extends BSTR implements + public static class ByReference extends LPOLESTR implements Structure.ByReference { } @@ -233,6 +290,8 @@ } public static class VARTYPE extends USHORT { + private static final long serialVersionUID = 1L; + public VARTYPE() { this(0); } @@ -241,4 +300,28 @@ super(value); } } + + public static class VARTYPEByReference extends ByReference { + public VARTYPEByReference() { + super(VARTYPE.SIZE); + } + + public VARTYPEByReference(VARTYPE type) { + super(VARTYPE.SIZE); + setValue(type); + } + + public VARTYPEByReference(short type) { + super(VARTYPE.SIZE); + getPointer().setShort(0, type); + } + + public void setValue(VARTYPE value) { + getPointer().setShort(0, value.shortValue()); + } + + public VARTYPE getValue() { + return new VARTYPE(getPointer().getShort(0)); + } + } } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/wince/CoreDLL.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/wince/CoreDLL.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/wince/CoreDLL.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/wince/CoreDLL.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,17 +1,29 @@ /* Copyright (c) 2011 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

    - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.wince; +import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.platform.win32.WinNT; import com.sun.jna.win32.W32APIOptions; @@ -19,10 +31,8 @@ /** Definition coredll.dll. Add other win32 interface mappings as needed. */ -public interface CoreDLL extends WinNT { +public interface CoreDLL extends WinNT, Library { - CoreDLL INSTANCE = (CoreDLL) - Native.loadLibrary("coredll", CoreDLL.class, - W32APIOptions.UNICODE_OPTIONS); + CoreDLL INSTANCE = Native.loadLibrary("coredll", CoreDLL.class, W32APIOptions.UNICODE_OPTIONS); } diff -Nru libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/WindowUtils.java libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/WindowUtils.java --- libjna-java-4.2.2/contrib/platform/src/com/sun/jna/platform/WindowUtils.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/src/com/sun/jna/platform/WindowUtils.java 2017-03-14 19:31:03.000000000 +0000 @@ -2,14 +2,26 @@ * Copyright (c) 2007-2008 Timothy Wall, All Rights Reserved * Parts Copyright (c) 2007 Olivier Chafik * - * This library is free software; you can - * redistribute it and/or modify it under the terms of the GNU Lesser - * General Public License as published by the Free Software Foundation; - * either version 2.1 of the License, or (at your option) any later - * version.

    This library is distributed in the hope that it will be - * useful, but WITHOUT ANY WARRANTY; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; @@ -45,6 +57,7 @@ import java.awt.geom.PathIterator; import java.awt.image.BufferedImage; import java.awt.image.Raster; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; @@ -76,20 +89,23 @@ import com.sun.jna.platform.win32.Psapi; import com.sun.jna.platform.win32.User32; import com.sun.jna.platform.win32.Win32Exception; -import com.sun.jna.platform.win32.WinNT; import com.sun.jna.platform.win32.WinDef.DWORDByReference; import com.sun.jna.platform.win32.WinDef.HBITMAP; import com.sun.jna.platform.win32.WinDef.HDC; import com.sun.jna.platform.win32.WinDef.HICON; import com.sun.jna.platform.win32.WinDef.HRGN; import com.sun.jna.platform.win32.WinDef.HWND; +import com.sun.jna.platform.win32.WinDef.LPARAM; +import com.sun.jna.platform.win32.WinDef.LRESULT; import com.sun.jna.platform.win32.WinDef.POINT; import com.sun.jna.platform.win32.WinDef.RECT; +import com.sun.jna.platform.win32.WinDef.WPARAM; import com.sun.jna.platform.win32.WinGDI; import com.sun.jna.platform.win32.WinGDI.BITMAP; import com.sun.jna.platform.win32.WinGDI.BITMAPINFO; import com.sun.jna.platform.win32.WinGDI.BITMAPINFOHEADER; import com.sun.jna.platform.win32.WinGDI.ICONINFO; +import com.sun.jna.platform.win32.WinNT; import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.platform.win32.WinUser; import com.sun.jna.platform.win32.WinUser.BLENDFUNCTION; @@ -134,9 +150,9 @@ * set to its final value before the heavyweight peer for the Window * is created. Once {@link Component#addNotify} has been called on the * component, causing creation of the heavyweight peer, changing this - * property has no effect. + * property has no effect. * @see Apple Technote 2007 - * + * * @author Andreas "PAX" Lück, onkelpax-git[at]yahoo.de */ // TODO: setWindowMask() should accept a threshold; some cases want a @@ -175,6 +191,7 @@ packed = true; } + @Override public boolean isVisible() { // Only want to be 'visible' once the peer is instantiated // via pack; this tricks PopupFactory into using a heavyweight @@ -182,6 +199,7 @@ return packed; } + @Override public Rectangle getBounds() { return getOwner().getBounds(); } @@ -197,27 +215,34 @@ protected class Listener extends WindowAdapter implements ComponentListener, HierarchyListener, AWTEventListener { + @Override public void windowOpened(WindowEvent e) { repaint(); } + @Override public void componentHidden(ComponentEvent e) {} + @Override public void componentMoved(ComponentEvent e) {} + @Override public void componentResized(ComponentEvent e) { setSize(getParent().getSize()); repaint(); } + @Override public void componentShown(ComponentEvent e) { repaint(); } + @Override public void hierarchyChanged(HierarchyEvent e) { repaint(); } + @Override public void eventDispatched(AWTEvent e) { if (e instanceof MouseEvent) { Component src = ((MouseEvent)e).getComponent(); @@ -240,6 +265,7 @@ this.content = content; } + @Override public void addNotify() { super.addNotify(); Window w = SwingUtilities.getWindowAncestor(this); @@ -249,6 +275,7 @@ Toolkit.getDefaultToolkit().addAWTEventListener(listener, AWTEvent.MOUSE_EVENT_MASK|AWTEvent.MOUSE_MOTION_EVENT_MASK); } + @Override public void removeNotify() { Toolkit.getDefaultToolkit().removeAWTEventListener(listener); Window w = SwingUtilities.getWindowAncestor(this); @@ -258,6 +285,7 @@ } private Rectangle dirty; + @Override protected void paintComponent(Graphics g) { Rectangle bounds = g.getClipBounds(); if (dirty == null || !dirty.contains(bounds)) { @@ -293,10 +321,12 @@ ((JComponent)oldContent).setOpaque(false); } } + @Override public void addNotify() { super.addNotify(); Toolkit.getDefaultToolkit().addAWTEventListener(this, AWTEvent.CONTAINER_EVENT_MASK); } + @Override public void removeNotify() { Toolkit.getDefaultToolkit().removeAWTEventListener(this); super.removeNotify(); @@ -307,6 +337,7 @@ setDoubleBuffered(!transparent); repaint(); } + @Override public void eventDispatched(AWTEvent e) { if (e.getID() == ContainerEvent.COMPONENT_ADDED && SwingUtilities.isDescendingFrom(((ContainerEvent)e).getChild(), this)) { @@ -314,6 +345,7 @@ NativeWindowUtils.this.setDoubleBuffered(child, false); } } + @Override public void paint(Graphics gr) { if (transparent) { Rectangle r = gr.getClipBounds(); @@ -360,10 +392,12 @@ } else if (Holder.requiresVisible) { getWindow(w).addWindowListener(new WindowAdapter() { + @Override public void windowOpened(WindowEvent e) { e.getWindow().removeWindowListener(this); action.run(); } + @Override public void windowClosed(WindowEvent e) { e.getWindow().removeWindowListener(this); } @@ -373,6 +407,7 @@ // Hierarchy events are fired in direct response to // displayability changes w.addHierarchyListener(new HierarchyListener() { + @Override public void hierarchyChanged(HierarchyEvent e) { if ((e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0 && e.getComponent().isDisplayable()) { @@ -425,6 +460,7 @@ protected Shape toShape(Raster raster) { final Area area = new Area(new Rectangle(0, 0, 0, 0)); RasterRangesUtils.outputOccupiedRanges(raster, new RasterRangesUtils.RangesOutput() { + @Override public boolean outputRange(int x, int y, int w, int h) { area.add(new Area(new Rectangle(x, y, w, h))); return true; @@ -489,15 +525,12 @@ JComponent content = (c instanceof JComponent) ? (JComponent)c : null; if (transparent) { - lp.putClientProperty(TRANSPARENT_OLD_OPAQUE, - Boolean.valueOf(lp.isOpaque())); + lp.putClientProperty(TRANSPARENT_OLD_OPAQUE, Boolean.valueOf(lp.isOpaque())); lp.setOpaque(false); - root.putClientProperty(TRANSPARENT_OLD_OPAQUE, - Boolean.valueOf(root.isOpaque())); + root.putClientProperty(TRANSPARENT_OLD_OPAQUE, Boolean.valueOf(root.isOpaque())); root.setOpaque(false); if (content != null) { - content.putClientProperty(TRANSPARENT_OLD_OPAQUE, - Boolean.valueOf(content.isOpaque())); + content.putClientProperty(TRANSPARENT_OLD_OPAQUE, Boolean.valueOf(content.isOpaque())); content.setOpaque(false); } root.putClientProperty(TRANSPARENT_OLD_BG, @@ -580,7 +613,7 @@ * The concerning window handle. * @return Either the window's icon or {@code null} if an error * occurred. - * + * * @throws UnsupportedOperationException * Thrown if this method wasn't yet implemented for the * current platform. @@ -588,7 +621,7 @@ protected BufferedImage getWindowIcon(final HWND hwnd) { throw new UnsupportedOperationException("This platform is not supported, yet."); } - + /** * Detects the size of an icon. * @@ -596,7 +629,7 @@ * The icon handle type. * @return Either the requested icon's dimension or an {@link Dimension} * instance of {@code (0, 0)}. - * + * * @throws UnsupportedOperationException * Thrown if this method wasn't yet implemented for the * current platform. @@ -604,7 +637,7 @@ protected Dimension getIconSize(final HICON hIcon) { throw new UnsupportedOperationException("This platform is not supported, yet."); } - + /** * Requests a list of all currently available Desktop windows. * @@ -617,7 +650,7 @@ * >User32.IsWindowVisible(HWND)). * * @return A list with all windows and some detailed information. - * + * * @throws UnsupportedOperationException * Thrown if this method wasn't yet implemented for the * current platform. @@ -625,7 +658,7 @@ protected List getAllWindows(final boolean onlyVisibleWindows) { throw new UnsupportedOperationException("This platform is not supported, yet."); } - + /** * Tries to obtain the Window's title which belongs to the specified * window handle. @@ -634,14 +667,14 @@ * The concerning window handle. * @return Either the title or an empty string of no title was found or * an error occurred. - * + * * @throws UnsupportedOperationException * Thrown if this method wasn't yet implemented for the */ protected String getWindowTitle(final HWND hwnd) { throw new UnsupportedOperationException("This platform is not supported, yet."); } - + /** * Detects the full file path of the process associated with the specified * window handle. @@ -651,14 +684,14 @@ * required. * @return The full file path of the PE file that is associated with the * specified window handle. - * + * * @throws UnsupportedOperationException * Thrown if this method wasn't yet implemented for the */ protected String getProcessFilePath(final HWND hwnd){ throw new UnsupportedOperationException("This platform is not supported, yet."); } - + /** * Requests the location and size of the window associated with the * specified window handle. @@ -666,7 +699,7 @@ * @param hwnd * The concerning window handle. * @return The location and size of the window. - * + * * @throws UnsupportedOperationException * Thrown if this method wasn't yet implemented for the */ @@ -717,6 +750,7 @@ * W32 alpha will only work if sun.java2d.noddraw * is set */ + @Override public boolean isWindowAlphaSupported() { return Boolean.getBoolean("sun.java2d.noddraw"); } @@ -736,7 +770,7 @@ private void storeAlpha(Window w, byte alpha) { if (w instanceof RootPaneContainer) { JRootPane root = ((RootPaneContainer)w).getRootPane(); - Byte b = alpha == (byte)0xFF ? null : new Byte(alpha); + Byte b = alpha == (byte)0xFF ? null : Byte.valueOf(alpha); root.putClientProperty(TRANSPARENT_ALPHA, b); } } @@ -753,11 +787,13 @@ return (byte)0xFF; } + @Override public void setWindowAlpha(final Window w, final float alpha) { if (!isWindowAlphaSupported()) { throw new UnsupportedOperationException("Set sun.java2d.noddraw=true to enable transparent windows"); } whenDisplayable(w, new Runnable() { + @Override public void run() { HWND hWnd = getHWnd(w); User32 user = User32.INSTANCE; @@ -813,16 +849,19 @@ memDC = null; } } + @Override public void removeNotify() { super.removeNotify(); disposeBackingStore(); } + @Override public void setTransparent(boolean transparent) { super.setTransparent(transparent); if (!transparent) { disposeBackingStore(); } } + @Override protected void paintDirect(BufferedImage buf, Rectangle bounds) { // TODO: paint frame decoration if window is decorated Window win = SwingUtilities.getWindowAncestor(this); @@ -914,6 +953,7 @@ /** Note that w32 does not paint window decorations when * the window is transparent. */ + @Override public void setWindowTransparent(final Window w, final boolean transparent) { if (!(w instanceof RootPaneContainer)) { @@ -927,6 +967,7 @@ if (transparent == isTransparent) return; whenDisplayable(w, new Runnable() { + @Override public void run() { User32 user = User32.INSTANCE; HWND hWnd = getHWnd(w); @@ -959,6 +1000,7 @@ }); } + @Override public void setWindowMask(final Component w, final Shape mask) { if (mask instanceof Area && ((Area)mask).isPolygonal()) { setMask(w, (Area)mask); @@ -971,6 +1013,7 @@ // NOTE: Deletes hrgn after setting the window region private void setWindowRegion(final Component w, final HRGN hrgn) { whenDisplayable(w, new Runnable() { + @Override public void run() { GDI32 gdi = GDI32.INSTANCE; User32 user = User32.INSTANCE; @@ -1007,7 +1050,7 @@ points.add(new POINT((int)coords[0], (int)coords[1])); } else if (type == PathIterator.SEG_CLOSE) { - sizes.add(new Integer(size)); + sizes.add(Integer.valueOf(size)); } else { throw new RuntimeException("Area is not polygonal: " + area); @@ -1028,6 +1071,7 @@ setWindowRegion(w, hrgn); } + @Override protected void setMask(final Component w, final Raster raster) { GDI32 gdi = GDI32.INSTANCE; final HRGN region = raster != null @@ -1036,6 +1080,7 @@ final HRGN tempRgn = gdi.CreateRectRgn(0, 0, 0, 0); try { RasterRangesUtils.outputOccupiedRanges(raster, new RasterRangesUtils.RangesOutput() { + @Override public boolean outputRange(int x, int y, int w, int h) { GDI32 gdi = GDI32.INSTANCE; gdi.SetRectRgn(tempRgn, x, y, x + w, y + h); @@ -1050,207 +1095,218 @@ setWindowRegion(w, region); } - @Override - public BufferedImage getWindowIcon(final HWND hwnd) { - // request different kind of icons if any solution fails - final DWORDByReference hIconNumber = new DWORDByReference(); - long result = User32.INSTANCE.SendMessageTimeout(hwnd, - WinUser.WM_GETICON, WinUser.ICON_BIG, 0, - WinUser.SMTO_ABORTIFHUNG, 500, hIconNumber); - if (result == 0) - result = User32.INSTANCE.SendMessageTimeout(hwnd, - WinUser.WM_GETICON, WinUser.ICON_SMALL, 0, - WinUser.SMTO_ABORTIFHUNG, 500, hIconNumber); - if (result == 0) - result = User32.INSTANCE.SendMessageTimeout(hwnd, - WinUser.WM_GETICON, WinUser.ICON_SMALL2, 0, - WinUser.SMTO_ABORTIFHUNG, 500, hIconNumber); - if (result == 0) { - result = User32.INSTANCE.GetClassLongPtr(hwnd, - WinUser.GCLP_HICON); - hIconNumber.getValue().setValue(result); - } - if (result == 0) { - result = User32.INSTANCE.GetClassLongPtr(hwnd, - WinUser.GCLP_HICONSM); - hIconNumber.getValue().setValue(result); - } - if (result == 0) - return null; - - // draw native icon into Java image - final HICON hIcon = new HICON(new Pointer(hIconNumber.getValue() - .longValue())); - final Dimension iconSize = getIconSize(hIcon); - if (iconSize.width == 0 || iconSize.height == 0) - return null; - - final int width = iconSize.width; - final int height = iconSize.height; - final short depth = 24; - - final byte[] lpBitsColor = new byte[width * height * depth / 8]; - final Pointer lpBitsColorPtr = new Memory(lpBitsColor.length); - final byte[] lpBitsMask = new byte[width * height * depth / 8]; - final Pointer lpBitsMaskPtr = new Memory(lpBitsMask.length); - final BITMAPINFO bitmapInfo = new BITMAPINFO(); - final BITMAPINFOHEADER hdr = new BITMAPINFOHEADER(); - - bitmapInfo.bmiHeader = hdr; - hdr.biWidth = width; - hdr.biHeight = height; - hdr.biPlanes = 1; - hdr.biBitCount = depth; - hdr.biCompression = 0; - hdr.write(); - bitmapInfo.write(); - - final HDC hDC = User32.INSTANCE.GetDC(null); - final ICONINFO iconInfo = new ICONINFO(); - User32.INSTANCE.GetIconInfo(hIcon, iconInfo); - iconInfo.read(); - GDI32.INSTANCE.GetDIBits(hDC, iconInfo.hbmColor, 0, height, - lpBitsColorPtr, bitmapInfo, 0); - lpBitsColorPtr.read(0, lpBitsColor, 0, lpBitsColor.length); - GDI32.INSTANCE.GetDIBits(hDC, iconInfo.hbmMask, 0, height, - lpBitsMaskPtr, bitmapInfo, 0); - lpBitsMaskPtr.read(0, lpBitsMask, 0, lpBitsMask.length); - final BufferedImage image = new BufferedImage(width, height, - BufferedImage.TYPE_INT_ARGB); - - int r, g, b, a, argb; - int x = 0, y = height - 1; - for (int i = 0; i < lpBitsColor.length; i = i + 3) { - b = lpBitsColor[i] & 0xFF; - g = lpBitsColor[i + 1] & 0xFF; - r = lpBitsColor[i + 2] & 0xFF; - a = 0xFF - lpBitsMask[i] & 0xFF; - argb = (a << 24) | (r << 16) | (g << 8) | b; - image.setRGB(x, y, argb); - x = (x + 1) % width; - if (x == 0) - y--; - } - - User32.INSTANCE.ReleaseDC(null, hDC); - - return image; - } - - @Override - public Dimension getIconSize(final HICON hIcon) { - final ICONINFO iconInfo = new ICONINFO(); - try { - if (!User32.INSTANCE.GetIconInfo(hIcon, iconInfo)) - return new Dimension(); - iconInfo.read(); - - final BITMAP bmp = new BITMAP(); - if (iconInfo.hbmColor != null - && iconInfo.hbmColor.getPointer() != Pointer.NULL) { - final int nWrittenBytes = GDI32.INSTANCE.GetObject( - iconInfo.hbmColor, bmp.size(), bmp.getPointer()); - bmp.read(); - if (nWrittenBytes > 0) - return new Dimension(bmp.bmWidth.intValue(), - bmp.bmHeight.intValue()); - } else if (iconInfo.hbmMask != null - && iconInfo.hbmMask.getPointer() != Pointer.NULL) { - final int nWrittenBytes = GDI32.INSTANCE.GetObject( - iconInfo.hbmMask, bmp.size(), bmp.getPointer()); - bmp.read(); - if (nWrittenBytes > 0) - return new Dimension(bmp.bmWidth.intValue(), bmp.bmHeight.intValue() / 2); - } - } finally { - if (iconInfo.hbmColor != null - && iconInfo.hbmColor.getPointer() != Pointer.NULL) - GDI32.INSTANCE.DeleteObject(iconInfo.hbmColor); - if (iconInfo.hbmMask != null - && iconInfo.hbmMask.getPointer() != Pointer.NULL) - GDI32.INSTANCE.DeleteObject(iconInfo.hbmMask); - } - - return new Dimension(); - } - - @Override - public List getAllWindows( - final boolean onlyVisibleWindows) { - final List result = new LinkedList(); + @Override + public BufferedImage getWindowIcon(final HWND hwnd) { + // request different kind of icons if any solution fails + final DWORDByReference hIconNumber = new DWORDByReference(); + LRESULT result = User32.INSTANCE + .SendMessageTimeout(hwnd, + WinUser.WM_GETICON, + new WPARAM(WinUser.ICON_BIG), + new LPARAM(0), + WinUser.SMTO_ABORTIFHUNG, 500, hIconNumber); + if (result.intValue() == 0) + result = User32.INSTANCE + .SendMessageTimeout(hwnd, + WinUser.WM_GETICON, + new WPARAM(WinUser.ICON_SMALL), + new LPARAM(0), + WinUser.SMTO_ABORTIFHUNG, 500, hIconNumber); + if (result.intValue() == 0) + result = User32.INSTANCE + .SendMessageTimeout(hwnd, + WinUser.WM_GETICON, + new WPARAM(WinUser.ICON_SMALL2), + new LPARAM(0), + WinUser.SMTO_ABORTIFHUNG, 500, hIconNumber); + if (result.intValue() == 0) { + result = new LRESULT(User32.INSTANCE + .GetClassLongPtr(hwnd, + WinUser.GCLP_HICON).intValue()); + hIconNumber.getValue().setValue(result.intValue()); + } + if (result.intValue() == 0) { + result = new LRESULT(User32.INSTANCE + .GetClassLongPtr(hwnd, + WinUser.GCLP_HICONSM).intValue()); + hIconNumber.getValue().setValue(result.intValue()); + } + if (result.intValue() == 0) + return null; + + // draw native icon into Java image + final HICON hIcon = new HICON(new Pointer(hIconNumber.getValue() + .longValue())); + final Dimension iconSize = getIconSize(hIcon); + if (iconSize.width == 0 || iconSize.height == 0) + return null; - final WNDENUMPROC lpEnumFunc = new WNDENUMPROC() { - @Override - public boolean callback(final HWND hwnd, final Pointer arg1) { - try { - final boolean visible = !onlyVisibleWindows - || User32.INSTANCE.IsWindowVisible(hwnd); - if (visible) { - final String title = getWindowTitle(hwnd); - final String filePath = getProcessFilePath(hwnd); - final Rectangle locAndSize = getWindowLocationAndSize(hwnd); - result.add(new DesktopWindow(hwnd, title, filePath, - locAndSize)); - } - } catch (final Exception e) { - e.printStackTrace(); - } - - return true; - } - }; - - if (!User32.INSTANCE.EnumWindows(lpEnumFunc, null)) - throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); - - return result; - } - - @Override - public String getWindowTitle(final HWND hwnd) { - final int requiredLength = User32.INSTANCE - .GetWindowTextLength(hwnd) + 1; - final char[] title = new char[requiredLength]; - final int length = User32.INSTANCE.GetWindowText(hwnd, title, - title.length); - - return Native.toString(Arrays.copyOfRange(title, 0, length)); - } - - @Override - public String getProcessFilePath(final HWND hwnd) { - final char[] filePath = new char[1025]; - final IntByReference pid = new IntByReference(); - User32.INSTANCE.GetWindowThreadProcessId(hwnd, pid); - - final HANDLE process = Kernel32.INSTANCE.OpenProcess( - WinNT.PROCESS_QUERY_INFORMATION | WinNT.PROCESS_VM_READ, - false, pid.getValue()); - if (process == null - && Kernel32.INSTANCE.GetLastError() != WinNT.ERROR_ACCESS_DENIED) - throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); - - final int length = Psapi.INSTANCE.GetModuleFileNameExW(process, - null, filePath, filePath.length); - if (length == 0 - && Kernel32.INSTANCE.GetLastError() != WinNT.ERROR_INVALID_HANDLE) - throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); - - return Native.toString(filePath).trim(); - } - - @Override - public Rectangle getWindowLocationAndSize(final HWND hwnd) { - final RECT lpRect = new RECT(); - if (!User32.INSTANCE.GetWindowRect(hwnd, lpRect)) - throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); - - return new Rectangle(lpRect.left, lpRect.top, Math.abs(lpRect.right - - lpRect.left), Math.abs(lpRect.bottom - lpRect.top)); - } - } + final int width = iconSize.width; + final int height = iconSize.height; + final short depth = 24; + + final byte[] lpBitsColor = new byte[width * height * depth / 8]; + final Pointer lpBitsColorPtr = new Memory(lpBitsColor.length); + final byte[] lpBitsMask = new byte[width * height * depth / 8]; + final Pointer lpBitsMaskPtr = new Memory(lpBitsMask.length); + final BITMAPINFO bitmapInfo = new BITMAPINFO(); + final BITMAPINFOHEADER hdr = new BITMAPINFOHEADER(); + + bitmapInfo.bmiHeader = hdr; + hdr.biWidth = width; + hdr.biHeight = height; + hdr.biPlanes = 1; + hdr.biBitCount = depth; + hdr.biCompression = 0; + hdr.write(); + bitmapInfo.write(); + + final HDC hDC = User32.INSTANCE.GetDC(null); + final ICONINFO iconInfo = new ICONINFO(); + User32.INSTANCE.GetIconInfo(hIcon, iconInfo); + iconInfo.read(); + GDI32.INSTANCE.GetDIBits(hDC, iconInfo.hbmColor, 0, height, + lpBitsColorPtr, bitmapInfo, 0); + lpBitsColorPtr.read(0, lpBitsColor, 0, lpBitsColor.length); + GDI32.INSTANCE.GetDIBits(hDC, iconInfo.hbmMask, 0, height, + lpBitsMaskPtr, bitmapInfo, 0); + lpBitsMaskPtr.read(0, lpBitsMask, 0, lpBitsMask.length); + final BufferedImage image = new BufferedImage(width, height, + BufferedImage.TYPE_INT_ARGB); + + int r, g, b, a, argb; + int x = 0, y = height - 1; + for (int i = 0; i < lpBitsColor.length; i = i + 3) { + b = lpBitsColor[i] & 0xFF; + g = lpBitsColor[i + 1] & 0xFF; + r = lpBitsColor[i + 2] & 0xFF; + a = 0xFF - lpBitsMask[i] & 0xFF; + argb = (a << 24) | (r << 16) | (g << 8) | b; + image.setRGB(x, y, argb); + x = (x + 1) % width; + if (x == 0) + y--; + } + + User32.INSTANCE.ReleaseDC(null, hDC); + + return image; + } + + @Override + public Dimension getIconSize(final HICON hIcon) { + final ICONINFO iconInfo = new ICONINFO(); + try { + if (!User32.INSTANCE.GetIconInfo(hIcon, iconInfo)) + return new Dimension(); + iconInfo.read(); + + final BITMAP bmp = new BITMAP(); + if (iconInfo.hbmColor != null + && iconInfo.hbmColor.getPointer() != Pointer.NULL) { + final int nWrittenBytes = GDI32.INSTANCE.GetObject( + iconInfo.hbmColor, bmp.size(), bmp.getPointer()); + bmp.read(); + if (nWrittenBytes > 0) + return new Dimension(bmp.bmWidth.intValue(), + bmp.bmHeight.intValue()); + } else if (iconInfo.hbmMask != null + && iconInfo.hbmMask.getPointer() != Pointer.NULL) { + final int nWrittenBytes = GDI32.INSTANCE.GetObject( + iconInfo.hbmMask, bmp.size(), bmp.getPointer()); + bmp.read(); + if (nWrittenBytes > 0) + return new Dimension(bmp.bmWidth.intValue(), bmp.bmHeight.intValue() / 2); + } + } finally { + if (iconInfo.hbmColor != null + && iconInfo.hbmColor.getPointer() != Pointer.NULL) + GDI32.INSTANCE.DeleteObject(iconInfo.hbmColor); + if (iconInfo.hbmMask != null + && iconInfo.hbmMask.getPointer() != Pointer.NULL) + GDI32.INSTANCE.DeleteObject(iconInfo.hbmMask); + } + + return new Dimension(); + } + + @Override + public List getAllWindows(final boolean onlyVisibleWindows) { + final List result = new LinkedList(); + + final WNDENUMPROC lpEnumFunc = new WNDENUMPROC() { + @Override + public boolean callback(final HWND hwnd, final Pointer arg1) { + try { + final boolean visible = !onlyVisibleWindows + || User32.INSTANCE.IsWindowVisible(hwnd); + if (visible) { + final String title = getWindowTitle(hwnd); + final String filePath = getProcessFilePath(hwnd); + final Rectangle locAndSize = getWindowLocationAndSize(hwnd); + result.add(new DesktopWindow(hwnd, title, filePath, + locAndSize)); + } + } catch (final Exception e) { + // FIXME properly handle whatever error is raised + e.printStackTrace(); + } + + return true; + } + }; + + if (!User32.INSTANCE.EnumWindows(lpEnumFunc, null)) + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + + return result; + } + + @Override + public String getWindowTitle(final HWND hwnd) { + final int requiredLength = User32.INSTANCE + .GetWindowTextLength(hwnd) + 1; + final char[] title = new char[requiredLength]; + final int length = User32.INSTANCE.GetWindowText(hwnd, title, + title.length); + + return Native.toString(Arrays.copyOfRange(title, 0, length)); + } + + @Override + public String getProcessFilePath(final HWND hwnd) { + final char[] filePath = new char[2048]; + final IntByReference pid = new IntByReference(); + User32.INSTANCE.GetWindowThreadProcessId(hwnd, pid); + + final HANDLE process = Kernel32.INSTANCE.OpenProcess(WinNT.PROCESS_QUERY_INFORMATION | WinNT.PROCESS_VM_READ, + false, pid.getValue()); + if (process == null + && Kernel32.INSTANCE.GetLastError() != WinNT.ERROR_ACCESS_DENIED) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + final int length = Psapi.INSTANCE.GetModuleFileNameExW(process, + null, filePath, filePath.length); + if (length == 0 + && Kernel32.INSTANCE.GetLastError() != WinNT.ERROR_INVALID_HANDLE) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + return Native.toString(filePath).trim(); + } + + @Override + public Rectangle getWindowLocationAndSize(final HWND hwnd) { + final RECT lpRect = new RECT(); + if (!User32.INSTANCE.GetWindowRect(hwnd, lpRect)) + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + + return new Rectangle(lpRect.left, lpRect.top, Math.abs(lpRect.right + - lpRect.left), Math.abs(lpRect.bottom - lpRect.top)); + } + } private static class MacWindowUtils extends NativeWindowUtils { + @Override public boolean isWindowAlphaSupported() { return true; } @@ -1291,6 +1347,7 @@ * property has no effect. * @see Apple Technote 2007 */ + @Override public void setWindowTransparent(Window w, boolean transparent) { boolean isTransparent = w.getBackground() != null && w.getBackground().getAlpha() == 0; @@ -1313,7 +1370,7 @@ } } } - + /** Note that the property * apple.awt.draggableWindowBackground must be set to its * final value before the heavyweight peer for the Window is @@ -1322,21 +1379,21 @@ * property has no effect. * @see Apple Technote 2007 */ + @Override public void setWindowAlpha(final Window w, final float alpha) { if (w instanceof RootPaneContainer) { JRootPane p = ((RootPaneContainer)w).getRootPane(); - p.putClientProperty("Window.alpha", new Float(alpha)); + p.putClientProperty("Window.alpha", Float.valueOf(alpha)); fixWindowDragging(w, "setWindowAlpha"); } whenDisplayable(w, new Runnable() { - public void run() { + @Override + public void run() { Object peer = w.getPeer(); try { - peer.getClass().getMethod("setAlpha", new Class[]{ - float.class - }).invoke(peer, new Object[]{ - new Float(alpha) - }); + Class cls = peer.getClass(); + Method m = cls.getMethod("setAlpha", new Class[]{ float.class }); + m.invoke(peer, Float.valueOf(alpha)); } catch (Exception e) { } @@ -1344,6 +1401,7 @@ }); } + @Override protected void setWindowMask(Component w, Raster raster) { if (raster != null) { setWindowMask(w, toShape(raster)); @@ -1354,6 +1412,7 @@ } } + @Override public void setWindowMask(Component c, final Shape shape) { if (c instanceof Window) { Window w = (Window)c; @@ -1385,6 +1444,7 @@ repaint(); } + @Override public void paint(Graphics graphics) { Graphics2D g = (Graphics2D)graphics.create(); g.setComposite(AlphaComposite.Clear); @@ -1448,6 +1508,7 @@ final List rlist = new ArrayList(); try { RasterRangesUtils.outputOccupiedRanges(raster, new RasterRangesUtils.RangesOutput() { + @Override public boolean outputRange(int x, int y, int w, int h) { rlist.add(new Rectangle(x, y, w, h)); return true; @@ -1483,6 +1544,7 @@ private boolean didCheck; private long[] alphaVisualIDs = {}; + @Override public boolean isWindowAlphaSupported() { return getAlphaVisualIDs().length > 0; } @@ -1497,12 +1559,14 @@ return ((Number)o).longValue(); } catch (Exception e) { + // FIXME properly handle this error e.printStackTrace(); return -1; } } /** Return the default graphics configuration. */ + @Override public GraphicsConfiguration getAlphaCompatibleGraphicsConfiguration() { if (isWindowAlphaSupported()) { GraphicsEnvironment env = @@ -1618,11 +1682,13 @@ private static final long OPAQUE = 0xFFFFFFFFL; private static final String OPACITY = "_NET_WM_WINDOW_OPACITY"; + @Override public void setWindowAlpha(final Window w, final float alpha) { if (!isWindowAlphaSupported()) { throw new UnsupportedOperationException("This X11 display does not provide a 32-bit visual"); } Runnable action = new Runnable() { + @Override public void run() { X11 x11 = X11.INSTANCE; Display dpy = x11.XOpenDisplay(null); @@ -1667,7 +1733,8 @@ // Painting directly to the original Graphics // fails to properly composite unless the destination // is pure black. Too bad. - protected void paintDirect(BufferedImage buf, Rectangle bounds) { + @Override + protected void paintDirect(BufferedImage buf, Rectangle bounds) { Window window = SwingUtilities.getWindowAncestor(this); X11 x11 = X11.INSTANCE; X11.Display dpy = x11.XOpenDisplay(null); @@ -1711,6 +1778,7 @@ } } + @Override public void setWindowTransparent(final Window w, final boolean transparent) { if (!(w instanceof RootPaneContainer)) { @@ -1728,6 +1796,7 @@ if (transparent == isTransparent) return; whenDisplayable(w, new Runnable() { + @Override public void run() { JRootPane root = ((RootPaneContainer)w).getRootPane(); JLayeredPane lp = root.getLayeredPane(); @@ -1755,6 +1824,7 @@ private void setWindowShape(final Window w, final PixmapSource src) { Runnable action = new Runnable() { + @Override public void run() { X11 x11 = X11.INSTANCE; Display dpy = x11.XOpenDisplay(null); @@ -1782,8 +1852,10 @@ whenDisplayable(w, action); } + @Override protected void setMask(final Component w, final Raster raster) { setWindowShape(getWindow(w), new PixmapSource() { + @Override public Pixmap getPixmap(Display dpy, X11.Window win) { return raster != null ? createBitmap(dpy, win, raster) : null; } @@ -1842,7 +1914,7 @@ * final value before the heavyweight peer for the Window is * created. Once {@link Component#addNotify} has been called on the * component, causing creation of the heavyweight peer, changing this - * property has no effect. + * property has no effect. * @see Apple Technote 2007 */ public static void setWindowAlpha(Window w, float alpha) { @@ -1853,7 +1925,7 @@ * Set the window to be transparent. Only explicitly painted pixels * will be non-transparent. All pixels will be composited with * whatever is under the window using their alpha values. - * + * * On OSX, the property apple.awt.draggableWindowBackground * must be set to its final value before the heavyweight peer for * the Window is created. Once {@link Component#addNotify} has been diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/mac/SystemBTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/mac/SystemBTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/mac/SystemBTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/mac/SystemBTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -24,7 +24,6 @@ import com.sun.jna.platform.mac.SystemB.VMStatistics64; import com.sun.jna.Memory; -import com.sun.jna.Native; import com.sun.jna.Platform; import com.sun.jna.Pointer; import com.sun.jna.ptr.IntByReference; @@ -153,7 +152,23 @@ assertEquals(procCpuLoadInfo.getValue().getIntArray(0, procInfoCount.getValue()).length, procInfoCount.getValue()); } - + + public void testMachPorts() { + int machPort = SystemB.INSTANCE.mach_host_self(); + assertTrue(machPort > 0); + machPort = SystemB.INSTANCE.mach_task_self(); + assertTrue(machPort > 0); + } + + public void testGetLoadAvg() { + double[] loadavg = new double[3]; + int retval = SystemB.INSTANCE.getloadavg(loadavg, 3); + assertEquals(retval, 3); + assertTrue(loadavg[0] >= 0); + assertTrue(loadavg[1] >= 0); + assertTrue(loadavg[2] >= 0); + } + public static void main(java.lang.String[] argList) { junit.textui.TestRunner.run(SystemBTest.class); } diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/mac/XAttrUtilTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/mac/XAttrUtilTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/mac/XAttrUtilTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/mac/XAttrUtilTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -84,7 +84,13 @@ } public void testUnicode() { - String[] names = new String[] { "中文", "にほんご", "Österreichisch", "Française", "Português" }; + String[] names = new String[] { + "\u4E2D\u6587", + "\u306B\u307B\u3093\u3054", + "\u00D6sterreichisch", + "Fran\u00E7aise", + "Portugu\u00EAs", + }; for (int i = 0; i < names.length; i++) { // set xattr XAttrUtil.setXAttr(testPath, names[i], names[i]); diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/unix/AbstractUnixTestSupport.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/unix/AbstractUnixTestSupport.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/unix/AbstractUnixTestSupport.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/unix/AbstractUnixTestSupport.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,42 @@ +/* Copyright (c) 2015 Goldstein Lyor, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ +package com.sun.jna.platform.unix; + +import com.sun.jna.Native; +import com.sun.jna.platform.AbstractPlatformTestSupport; + +/** + * @author Lyor Goldstein + */ +public abstract class AbstractUnixTestSupport extends AbstractPlatformTestSupport { + protected AbstractUnixTestSupport() { + super(); + } + + public static int getErrno() { + return Native.getLastError(); + } + + /** + * Checks if result is zero. If not, then throws an assertion error with the {@code errno} value + * + * @param message The failure message to prepend if necessary + * @param result The syscall result code + */ + public static void assertSuccessResult(String message, int result) { + if (result != 0) { + int errno = getErrno(); + fail(message + ": result=" + result + ", errno=" + errno); + } + } +} diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/unix/LibCTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/unix/LibCTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/unix/LibCTest.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/unix/LibCTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,61 @@ +/* Copyright (c) 2015 Goldstein Lyor, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ +package com.sun.jna.platform.unix; + +import java.sql.Date; +import java.util.Map; + +import org.junit.Test; + +/** + * @author Lyor Goldstein + */ +public class LibCTest extends AbstractUnixTestSupport { + public LibCTest() { + super(); + } + + @Test + public void testGetenv() { + Map env = System.getenv(); + for (Map.Entry ee : env.entrySet()) { + String name = ee.getKey(); + String expected = ee.getValue(); + String actual = LibC.INSTANCE.getenv(name); + assertEquals(name, expected, actual); + } + } + + @Test + public void testSetenv() { + String name = getCurrentTestName(); + try { + String expected = new Date(System.currentTimeMillis()).toString(); + assertSuccessResult("setenv", LibC.INSTANCE.setenv(name, expected, 1)); + assertEquals("Mismatched values", expected, LibC.INSTANCE.getenv(name)); + assertSuccessResult("unsetenv", LibC.INSTANCE.unsetenv(name)); + } finally { + LibC.INSTANCE.unsetenv(name); + } + } + + @Test + public void testGetLoadAvg() { + double[] loadavg = new double[3]; + int retval = LibC.INSTANCE.getloadavg(loadavg, 3); + assertEquals(retval, 3); + assertTrue(loadavg[0] >= 0); + assertTrue(loadavg[1] >= 0); + assertTrue(loadavg[2] >= 0); + } +} diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/unix/X11Test.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/unix/X11Test.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/unix/X11Test.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/unix/X11Test.java 2017-03-14 19:31:03.000000000 +0000 @@ -12,7 +12,13 @@ */ package com.sun.jna.platform.unix; +import java.awt.GraphicsEnvironment; + +import com.sun.jna.ptr.PointerByReference; +import com.sun.jna.ptr.IntByReference; + import junit.framework.TestCase; +import org.junit.Assert; /** * Exercise the {@link X11} class. @@ -22,12 +28,82 @@ // @SuppressWarnings("unused") public class X11Test extends TestCase { + private X11.Display display = null; + private X11.Window root = null; + + @Override + protected void setUp() { + if (!GraphicsEnvironment.isHeadless()) { + display = X11.INSTANCE.XOpenDisplay(null); + if (display == null) { + throw new IllegalStateException("Can't open default display"); + } + root = X11.INSTANCE.XRootWindow(display, X11.INSTANCE.XDefaultScreen(display)); + if (root == null) { + throw new IllegalStateException("Can't find root window"); + } + } + } + + @Override + protected void tearDown() { + if (display != null) { + X11.INSTANCE.XCloseDisplay(display); + } + } + + @Override + protected void runTest() throws Throwable { + if (!GraphicsEnvironment.isHeadless()) { + super.runTest(); + } + } + public void testXrender() { X11.Xrender.XRenderPictFormat s = new X11.Xrender.XRenderPictFormat(); s.getPointer().setInt(0, 25); s.read(); } + public void testXFetchName() { + PointerByReference pref = new PointerByReference(); + int status = X11.INSTANCE.XFetchName(display, root, pref); + try { + assertEquals("Bad status for XFetchName", 0, status); + } + finally { + if (pref.getValue() != null) { + X11.INSTANCE.XFree(pref.getValue()); + } + } + } + + public void testXSetWMProtocols() { + X11.Atom[] atoms = new X11.Atom[]{ X11.INSTANCE.XInternAtom(display, "WM_DELETE_WINDOW", false), X11.INSTANCE.XInternAtom(display, "WM_TAKE_FOCUS", false) }; + int status = X11.INSTANCE.XSetWMProtocols(display, root, atoms, atoms.length); + Assert.assertNotEquals("Bad status for XSetWMProtocols", 0, status); + } + + public void testXGetWMProtocols() { + X11.Atom[] sentAtoms = new X11.Atom[]{ X11.INSTANCE.XInternAtom(display, "WM_DELETE_WINDOW", false), X11.INSTANCE.XInternAtom(display, "WM_TAKE_FOCUS", false) }; + X11.INSTANCE.XSetWMProtocols(display, root, sentAtoms, sentAtoms.length); + + PointerByReference protocols = new PointerByReference(); + IntByReference count = new IntByReference(); + + int status = X11.INSTANCE.XGetWMProtocols(display, root, protocols, count); + + X11.Atom[] receivedAtoms = new X11.Atom[count.getValue()]; + for(int i = count.getValue() - 1; i >= 0; i--) { + receivedAtoms[i] = new X11.Atom(protocols.getValue().getLong(X11.Atom.SIZE * i)); + } + X11.INSTANCE.XFree(protocols.getValue()); + + Assert.assertNotEquals("Bad status for XGetWMProtocols", 0, status); + Assert.assertEquals("Wrong number of protocols returned for XGetWMProtocols", sentAtoms.length, receivedAtoms.length); + Assert.assertArrayEquals("Sent protocols were not equal to returned procols for XGetWMProtocols", sentAtoms, receivedAtoms); + } + public static void main(java.lang.String[] argList) { junit.textui.TestRunner.run(X11Test.class); } diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/AbstractWin32TestSupport.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/AbstractWin32TestSupport.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/AbstractWin32TestSupport.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/AbstractWin32TestSupport.java 2017-03-14 19:31:03.000000000 +0000 @@ -12,13 +12,18 @@ */ package com.sun.jna.platform.win32; +import com.sun.jna.Native; import java.lang.reflect.Method; import java.util.Collection; import java.util.HashSet; import java.util.Set; import com.sun.jna.platform.AbstractPlatformTestSupport; +import static com.sun.jna.platform.win32.Tlhelp32.TH32CS_SNAPALL; +import com.sun.jna.platform.win32.WinDef.LCID; import com.sun.jna.platform.win32.WinNT.HANDLE; +import java.util.Arrays; +import java.util.Collections; public abstract class AbstractWin32TestSupport extends AbstractPlatformTestSupport { protected AbstractWin32TestSupport() { @@ -116,4 +121,28 @@ return handle; } + + public static final LCID systemLCID = Kernel32.INSTANCE.GetSystemDefaultLCID(); + public static final boolean isEnglishLocale = + systemLCID.intValue() == 0x409 // en_US + || systemLCID.intValue() == 0x809 // en_GB + ; + + public static void killProcessByName(String filename) { + HANDLE hSnapShot = Kernel32.INSTANCE.CreateToolhelp32Snapshot(TH32CS_SNAPALL, null); + Tlhelp32.PROCESSENTRY32 process = new Tlhelp32.PROCESSENTRY32(); + boolean hRes = Kernel32.INSTANCE.Process32First(hSnapShot, process); + while (hRes) { + String imageName = Native.toString(process.szExeFile); + if (imageName.equalsIgnoreCase(filename)) { + HANDLE hProcess = Kernel32.INSTANCE.OpenProcess(Kernel32.PROCESS_TERMINATE, false, process.th32ProcessID.intValue()); + if (hProcess != null) { + Kernel32.INSTANCE.TerminateProcess(hProcess, 9); + Kernel32.INSTANCE.CloseHandle(hProcess); + } + } + hRes = Kernel32.INSTANCE.Process32Next(hSnapShot, process); + } + Kernel32.INSTANCE.CloseHandle(hSnapShot); + } } diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/Advapi32Test.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/Advapi32Test.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/Advapi32Test.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/Advapi32Test.java 2017-03-14 19:31:03.000000000 +0000 @@ -12,26 +12,62 @@ */ package com.sun.jna.platform.win32; +import static com.sun.jna.platform.win32.WinBase.CREATE_FOR_IMPORT; +import static com.sun.jna.platform.win32.WinBase.FILE_DIR_DISALOWED; +import static com.sun.jna.platform.win32.WinBase.FILE_ENCRYPTABLE; +import static com.sun.jna.platform.win32.WinBase.FILE_IS_ENCRYPTED; +import static com.sun.jna.platform.win32.WinBase.FILE_READ_ONLY; +import static com.sun.jna.platform.win32.WinNT.DACL_SECURITY_INFORMATION; +import static com.sun.jna.platform.win32.WinNT.FILE_ALL_ACCESS; +import static com.sun.jna.platform.win32.WinNT.FILE_GENERIC_EXECUTE; +import static com.sun.jna.platform.win32.WinNT.FILE_GENERIC_READ; +import static com.sun.jna.platform.win32.WinNT.FILE_GENERIC_WRITE; +import static com.sun.jna.platform.win32.WinNT.GENERIC_ALL; +import static com.sun.jna.platform.win32.WinNT.GENERIC_EXECUTE; +import static com.sun.jna.platform.win32.WinNT.GENERIC_READ; +import static com.sun.jna.platform.win32.WinNT.GENERIC_WRITE; +import static com.sun.jna.platform.win32.WinNT.GROUP_SECURITY_INFORMATION; +import static com.sun.jna.platform.win32.WinNT.OWNER_SECURITY_INFORMATION; +import static com.sun.jna.platform.win32.WinNT.SACL_SECURITY_INFORMATION; +import static com.sun.jna.platform.win32.WinNT.SE_RESTORE_NAME; +import static com.sun.jna.platform.win32.WinNT.SE_SECURITY_NAME; +import static com.sun.jna.platform.win32.WinNT.TOKEN_ADJUST_PRIVILEGES; +import static com.sun.jna.platform.win32.WinNT.TOKEN_DUPLICATE; +import static com.sun.jna.platform.win32.WinNT.TOKEN_IMPERSONATE; + import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.Collection; -import junit.framework.TestCase; - import com.sun.jna.Memory; import com.sun.jna.Native; import com.sun.jna.Pointer; -import com.sun.jna.WString; import com.sun.jna.platform.win32.LMAccess.USER_INFO_1; +import com.sun.jna.platform.win32.WinBase.FE_EXPORT_FUNC; +import com.sun.jna.platform.win32.WinBase.FE_IMPORT_FUNC; import com.sun.jna.platform.win32.WinBase.FILETIME; +import com.sun.jna.platform.win32.WinBase.PROCESS_INFORMATION; +import com.sun.jna.platform.win32.WinBase.STARTUPINFO; +import com.sun.jna.platform.win32.WinDef.BOOL; +import com.sun.jna.platform.win32.WinDef.BOOLByReference; import com.sun.jna.platform.win32.WinDef.DWORD; +import com.sun.jna.platform.win32.WinDef.DWORDByReference; +import com.sun.jna.platform.win32.WinDef.ULONG; +import com.sun.jna.platform.win32.WinDef.ULONGByReference; +import com.sun.jna.platform.win32.WinNT.ACCESS_ALLOWED_ACE; +import com.sun.jna.platform.win32.WinNT.ACL; import com.sun.jna.platform.win32.WinNT.EVENTLOGRECORD; +import com.sun.jna.platform.win32.WinNT.GENERIC_MAPPING; import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.platform.win32.WinNT.HANDLEByReference; +import com.sun.jna.platform.win32.WinNT.PACLByReference; +import com.sun.jna.platform.win32.WinNT.PRIVILEGE_SET; import com.sun.jna.platform.win32.WinNT.PSID; import com.sun.jna.platform.win32.WinNT.PSIDByReference; +import com.sun.jna.platform.win32.WinNT.SECURITY_DESCRIPTOR; +import com.sun.jna.platform.win32.WinNT.SECURITY_DESCRIPTOR_RELATIVE; import com.sun.jna.platform.win32.WinNT.SECURITY_IMPERSONATION_LEVEL; import com.sun.jna.platform.win32.WinNT.SID_AND_ATTRIBUTES; import com.sun.jna.platform.win32.WinNT.SID_NAME_USE; @@ -42,11 +78,11 @@ import com.sun.jna.platform.win32.Winsvc.SC_HANDLE; import com.sun.jna.platform.win32.Winsvc.SC_STATUS_TYPE; import com.sun.jna.platform.win32.Winsvc.SERVICE_STATUS_PROCESS; -import com.sun.jna.ptr.ByteByReference; import com.sun.jna.ptr.IntByReference; import com.sun.jna.ptr.PointerByReference; +import com.sun.jna.ptr.ShortByReference; -import static com.sun.jna.platform.win32.WinNT.*; +import junit.framework.TestCase; /** * @author dblock[at]dblock[dot]org @@ -108,60 +144,104 @@ String sidString = EVERYONE; PSIDByReference sid = new PSIDByReference(); assertTrue("SID conversion failed", Advapi32.INSTANCE.ConvertStringSidToSid(sidString, sid)); - assertTrue("Converted SID not valid: " + sid.getValue(), Advapi32.INSTANCE.IsValidSid(sid.getValue())); - int sidLength = Advapi32.INSTANCE.GetLengthSid(sid.getValue()); - assertTrue(sidLength > 0); - assertTrue(Advapi32.INSTANCE.IsValidSid(sid.getValue())); + + PSID value = sid.getValue(); + try { + assertTrue("Converted SID not valid: " + value, Advapi32.INSTANCE.IsValidSid(value)); + int sidLength = Advapi32.INSTANCE.GetLengthSid(value); + assertTrue("Non positive sid length", sidLength > 0); + assertTrue("Invalid sid", Advapi32.INSTANCE.IsValidSid(value)); + } finally { + Kernel32Util.freeLocalMemory(value.getPointer()); + } + } + + public void testEqualSid() { + String sidString = EVERYONE; + PSIDByReference sid1 = new PSIDByReference(); + PSIDByReference sid2 = new PSIDByReference(); + assertTrue("SID1 conversion failed", Advapi32.INSTANCE.ConvertStringSidToSid(sidString, sid1)); + assertTrue("SID2 conversion failed", Advapi32.INSTANCE.ConvertStringSidToSid(sidString, sid2)); + + try { + assertTrue("Converted SID1 not valid", Advapi32.INSTANCE.IsValidSid(sid1.getValue())); + assertTrue("Converted SID2 not valid", Advapi32.INSTANCE.IsValidSid(sid2.getValue())); + assertTrue("Invalid sid", Advapi32.INSTANCE.EqualSid(sid1.getValue(), sid2.getValue())); + } finally { + Kernel32Util.freeLocalMemory(sid1.getValue().getPointer()); + Kernel32Util.freeLocalMemory(sid2.getValue().getPointer()); + } } public void testGetSidLength() { String sidString = EVERYONE; PSIDByReference sid = new PSIDByReference(); assertTrue("SID conversion failed", Advapi32.INSTANCE.ConvertStringSidToSid(sidString, sid)); - assertEquals("Wrong SID lenght", 12, Advapi32.INSTANCE.GetLengthSid(sid.getValue())); + + PSID value = sid.getValue(); + try { + assertEquals("Wrong SID length", 12, Advapi32.INSTANCE.GetLengthSid(value)); + } finally { + Kernel32Util.freeLocalMemory(value.getPointer()); + } } public void testLookupAccountSid() { // get SID bytes String sidString = EVERYONE; PSIDByReference sid = new PSIDByReference(); - assertTrue(Advapi32.INSTANCE.ConvertStringSidToSid(sidString, sid)); - int sidLength = Advapi32.INSTANCE.GetLengthSid(sid.getValue()); - assertTrue(sidLength > 0); - // lookup account - IntByReference cchName = new IntByReference(); - IntByReference cchReferencedDomainName = new IntByReference(); - PointerByReference peUse = new PointerByReference(); - assertFalse(Advapi32.INSTANCE.LookupAccountSid(null, sid.getValue(), - null, cchName, null, cchReferencedDomainName, peUse)); - assertEquals(W32Errors.ERROR_INSUFFICIENT_BUFFER, Kernel32.INSTANCE.GetLastError()); - assertTrue(cchName.getValue() > 0); - assertTrue(cchReferencedDomainName.getValue() > 0); - char[] referencedDomainName = new char[cchReferencedDomainName.getValue()]; - char[] name = new char[cchName.getValue()]; - assertTrue(Advapi32.INSTANCE.LookupAccountSid(null, sid.getValue(), - name, cchName, referencedDomainName, cchReferencedDomainName, peUse)); - assertEquals(5, peUse.getPointer().getInt(0)); // SidTypeWellKnownGroup - String nameString = Native.toString(name); - String referencedDomainNameString = Native.toString(referencedDomainName); - assertTrue(nameString.length() > 0); - assertEquals("Everyone", nameString); - assertTrue(referencedDomainNameString.length() == 0); - assertEquals(null, Kernel32.INSTANCE.LocalFree(sid.getValue().getPointer())); + assertTrue("Failed to create sid", Advapi32.INSTANCE.ConvertStringSidToSid(sidString, sid)); + + PSID value = sid.getValue(); + try { + int sidLength = Advapi32.INSTANCE.GetLengthSid(value); + assertTrue("Non-positive sid length", sidLength > 0); + // lookup account + IntByReference cchName = new IntByReference(); + IntByReference cchReferencedDomainName = new IntByReference(); + PointerByReference peUse = new PointerByReference(); + assertFalse(Advapi32.INSTANCE.LookupAccountSid(null, value, + null, cchName, null, cchReferencedDomainName, peUse)); + assertEquals(W32Errors.ERROR_INSUFFICIENT_BUFFER, Kernel32.INSTANCE.GetLastError()); + assertTrue(cchName.getValue() > 0); + assertTrue(cchReferencedDomainName.getValue() > 0); + char[] referencedDomainName = new char[cchReferencedDomainName.getValue()]; + char[] name = new char[cchName.getValue()]; + assertTrue(Advapi32.INSTANCE.LookupAccountSid(null, value, + name, cchName, referencedDomainName, cchReferencedDomainName, peUse)); + assertEquals(5, peUse.getPointer().getInt(0)); // SidTypeWellKnownGroup + String nameString = Native.toString(name); + String referencedDomainNameString = Native.toString(referencedDomainName); + assertTrue(nameString.length() > 0); + if(AbstractWin32TestSupport.isEnglishLocale) { + assertEquals("Everyone", nameString); + } + assertTrue(referencedDomainNameString.length() == 0); + } finally { + Kernel32Util.freeLocalMemory(value.getPointer()); + } } public void testConvertSid() { String sidString = EVERYONE; PSIDByReference sid = new PSIDByReference(); - assertTrue(Advapi32.INSTANCE.ConvertStringSidToSid( - sidString, sid)); - PointerByReference convertedSidStringPtr = new PointerByReference(); - assertTrue(Advapi32.INSTANCE.ConvertSidToStringSid( - sid.getValue(), convertedSidStringPtr)); - String convertedSidString = convertedSidStringPtr.getValue().getWideString(0); - assertEquals(convertedSidString, sidString); - assertEquals(null, Kernel32.INSTANCE.LocalFree(convertedSidStringPtr.getValue())); - assertEquals(null, Kernel32.INSTANCE.LocalFree(sid.getValue().getPointer())); + assertTrue("Failed to convert SID string", Advapi32.INSTANCE.ConvertStringSidToSid(sidString, sid)); + + PSID value = sid.getValue(); + try { + PointerByReference convertedSidStringPtr = new PointerByReference(); + assertTrue("Failed to convert SID string", Advapi32.INSTANCE.ConvertSidToStringSid(value, convertedSidStringPtr)); + + Pointer conv = convertedSidStringPtr.getValue(); + try { + String convertedSidString = conv.getWideString(0); + assertEquals("Mismatched SID string", convertedSidString, sidString); + } finally { + Kernel32Util.freeLocalMemory(conv); + } + } finally { + Kernel32Util.freeLocalMemory(value.getPointer()); + } } public void testLogonUser() { @@ -182,182 +262,203 @@ public void testOpenProcessToken() { HANDLEByReference phToken = new HANDLEByReference(); - HANDLE processHandle = Kernel32.INSTANCE.GetCurrentProcess(); - assertTrue(Advapi32.INSTANCE.OpenProcessToken(processHandle, - WinNT.TOKEN_DUPLICATE | WinNT.TOKEN_QUERY, phToken)); - assertTrue(Kernel32.INSTANCE.CloseHandle(phToken.getValue())); - } - - public void testOpenThreadOrProcessToken() { - HANDLEByReference phToken = new HANDLEByReference(); - HANDLE threadHandle = Kernel32.INSTANCE.GetCurrentThread(); - if (! Advapi32.INSTANCE.OpenThreadToken(threadHandle, - WinNT.TOKEN_DUPLICATE | WinNT.TOKEN_QUERY, true, phToken)) { - assertEquals(W32Errors.ERROR_NO_TOKEN, Kernel32.INSTANCE.GetLastError()); + try { HANDLE processHandle = Kernel32.INSTANCE.GetCurrentProcess(); assertTrue(Advapi32.INSTANCE.OpenProcessToken(processHandle, WinNT.TOKEN_DUPLICATE | WinNT.TOKEN_QUERY, phToken)); + } finally { + Kernel32Util.closeHandleRef(phToken); } - assertTrue(Kernel32.INSTANCE.CloseHandle(phToken.getValue())); + } + + public void testOpenThreadOrProcessToken() { + HANDLEByReference phToken = new HANDLEByReference(); + try { + HANDLE threadHandle = Kernel32.INSTANCE.GetCurrentThread(); + if (! Advapi32.INSTANCE.OpenThreadToken(threadHandle, + WinNT.TOKEN_DUPLICATE | WinNT.TOKEN_QUERY, true, phToken)) { + assertEquals(W32Errors.ERROR_NO_TOKEN, Kernel32.INSTANCE.GetLastError()); + HANDLE processHandle = Kernel32.INSTANCE.GetCurrentProcess(); + assertTrue(Advapi32.INSTANCE.OpenProcessToken(processHandle, + WinNT.TOKEN_DUPLICATE | WinNT.TOKEN_QUERY, phToken)); + } + } finally { + Kernel32Util.closeHandleRef(phToken); + } } public void testSetThreadTokenCurrentThread() { HANDLEByReference phToken = new HANDLEByReference(); HANDLEByReference phTokenDup = new HANDLEByReference(); - HANDLE threadHandle = Kernel32.INSTANCE.GetCurrentThread(); - // See if thread has a token. If not, must duplicate process token and set thread token using that. - if (!Advapi32.INSTANCE.OpenThreadToken(threadHandle, - WinNT.TOKEN_IMPERSONATE | WinNT.TOKEN_QUERY, false, phToken)) { - assertEquals(W32Errors.ERROR_NO_TOKEN, Kernel32.INSTANCE.GetLastError()); - HANDLE processHandle = Kernel32.INSTANCE.GetCurrentProcess(); - assertTrue(Advapi32.INSTANCE.OpenProcessToken(processHandle, WinNT.TOKEN_DUPLICATE, phToken)); - assertTrue(Advapi32.INSTANCE.DuplicateTokenEx(phToken.getValue(), - WinNT.TOKEN_IMPERSONATE, - null, - WinNT.SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, - WinNT.TOKEN_TYPE.TokenImpersonation, - phTokenDup)); - // Null sets on current thread - assertTrue(Advapi32.INSTANCE.SetThreadToken(null, phTokenDup.getValue())); - } - else { - //Null sets on current thread - assertTrue(Advapi32.INSTANCE.SetThreadToken(null, phToken.getValue())); + try { + HANDLE threadHandle = Kernel32.INSTANCE.GetCurrentThread(); + // See if thread has a token. If not, must duplicate process token and set thread token using that. + if (!Advapi32.INSTANCE.OpenThreadToken(threadHandle, + WinNT.TOKEN_IMPERSONATE | WinNT.TOKEN_QUERY, false, phToken)) { + assertEquals(W32Errors.ERROR_NO_TOKEN, Kernel32.INSTANCE.GetLastError()); + HANDLE processHandle = Kernel32.INSTANCE.GetCurrentProcess(); + assertTrue(Advapi32.INSTANCE.OpenProcessToken(processHandle, WinNT.TOKEN_DUPLICATE, phToken)); + assertTrue(Advapi32.INSTANCE.DuplicateTokenEx(phToken.getValue(), + WinNT.TOKEN_IMPERSONATE, + null, + WinNT.SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, + WinNT.TOKEN_TYPE.TokenImpersonation, + phTokenDup)); + // Null sets on current thread + assertTrue(Advapi32.INSTANCE.SetThreadToken(null, phTokenDup.getValue())); + } + else { + //Null sets on current thread + assertTrue(Advapi32.INSTANCE.SetThreadToken(null, phToken.getValue())); + } + // Revert and cleanup + assertTrue(Advapi32.INSTANCE.SetThreadToken(null, null)); + } finally { + Kernel32Util.closeHandleRefs(phToken, phTokenDup); } - // Revert and cleanup - assertTrue(Advapi32.INSTANCE.SetThreadToken(null, null)); - assertTrue(Kernel32.INSTANCE.CloseHandle(phToken.getValue())); - if (phTokenDup.getValue() != null) - assertTrue(Kernel32.INSTANCE.CloseHandle(phTokenDup.getValue())); } public void testSetThreadTokenThisThread() { HANDLEByReference phToken = new HANDLEByReference(); HANDLEByReference phTokenDup = new HANDLEByReference(); - HANDLEByReference pthreadHandle = new HANDLEByReference(); - pthreadHandle.setValue(Kernel32.INSTANCE.GetCurrentThread()); - // See if thread has a token. If not, must duplicate process token and set thread token using that. - if (!Advapi32.INSTANCE.OpenThreadToken(pthreadHandle.getValue(), - WinNT.TOKEN_IMPERSONATE | WinNT.TOKEN_QUERY, false, phToken)) { - assertEquals(W32Errors.ERROR_NO_TOKEN, Kernel32.INSTANCE.GetLastError()); - HANDLE processHandle = Kernel32.INSTANCE.GetCurrentProcess(); - assertTrue(Advapi32.INSTANCE.OpenProcessToken(processHandle, - WinNT.TOKEN_DUPLICATE, phToken)); - assertTrue(Advapi32.INSTANCE.DuplicateTokenEx(phToken.getValue(), - WinNT.TOKEN_IMPERSONATE, - null, - WinNT.SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, - WinNT.TOKEN_TYPE.TokenImpersonation, - phTokenDup)); - // Use HANDLEByReference on this thread to test, should be good enough for API compatibility. - assertTrue(Advapi32.INSTANCE.SetThreadToken(pthreadHandle, phTokenDup.getValue())); - } - else { - // Use HANDLEByReference on this thread to test, should be good enough for API compatibility. - assertTrue(Advapi32.INSTANCE.SetThreadToken(pthreadHandle, phToken.getValue())); + try { + HANDLEByReference pthreadHandle = new HANDLEByReference(); + pthreadHandle.setValue(Kernel32.INSTANCE.GetCurrentThread()); + // See if thread has a token. If not, must duplicate process token and set thread token using that. + if (!Advapi32.INSTANCE.OpenThreadToken(pthreadHandle.getValue(), + WinNT.TOKEN_IMPERSONATE | WinNT.TOKEN_QUERY, false, phToken)) { + assertEquals(W32Errors.ERROR_NO_TOKEN, Kernel32.INSTANCE.GetLastError()); + HANDLE processHandle = Kernel32.INSTANCE.GetCurrentProcess(); + assertTrue(Advapi32.INSTANCE.OpenProcessToken(processHandle, + WinNT.TOKEN_DUPLICATE, phToken)); + assertTrue(Advapi32.INSTANCE.DuplicateTokenEx(phToken.getValue(), + WinNT.TOKEN_IMPERSONATE, + null, + WinNT.SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, + WinNT.TOKEN_TYPE.TokenImpersonation, + phTokenDup)); + // Use HANDLEByReference on this thread to test, should be good enough for API compatibility. + assertTrue(Advapi32.INSTANCE.SetThreadToken(pthreadHandle, phTokenDup.getValue())); + } + else { + // Use HANDLEByReference on this thread to test, should be good enough for API compatibility. + assertTrue(Advapi32.INSTANCE.SetThreadToken(pthreadHandle, phToken.getValue())); + } + // Revert and cleanup + assertTrue(Advapi32.INSTANCE.SetThreadToken(null, null)); + } finally { + Kernel32Util.closeHandleRefs(phToken, phTokenDup); } - // Revert and cleanup - assertTrue(Advapi32.INSTANCE.SetThreadToken(null, null)); - assertTrue(Kernel32.INSTANCE.CloseHandle(phToken.getValue())); - if (phTokenDup.getValue() != null) - assertTrue(Kernel32.INSTANCE.CloseHandle(phTokenDup.getValue())); } public void testDuplicateToken() { HANDLEByReference phToken = new HANDLEByReference(); HANDLEByReference phTokenDup = new HANDLEByReference(); HANDLE processHandle = Kernel32.INSTANCE.GetCurrentProcess(); - assertTrue(Advapi32.INSTANCE.OpenProcessToken(processHandle, - WinNT.TOKEN_DUPLICATE | WinNT.TOKEN_QUERY, phToken)); - assertTrue(Advapi32.INSTANCE.DuplicateToken(phToken.getValue(), - WinNT.SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, phTokenDup)); - assertTrue(Kernel32.INSTANCE.CloseHandle(phTokenDup.getValue())); - assertTrue(Kernel32.INSTANCE.CloseHandle(phToken.getValue())); + try { + assertTrue(Advapi32.INSTANCE.OpenProcessToken(processHandle, + WinNT.TOKEN_DUPLICATE | WinNT.TOKEN_QUERY, phToken)); + assertTrue(Advapi32.INSTANCE.DuplicateToken(phToken.getValue(), + WinNT.SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, phTokenDup)); + } finally { + Kernel32Util.closeHandleRefs(phTokenDup, phToken); + } } public void testDuplicateTokenEx() { HANDLEByReference hExistingToken = new HANDLEByReference(); HANDLEByReference phNewToken = new HANDLEByReference(); - HANDLE processHandle = Kernel32.INSTANCE.GetCurrentProcess(); - assertTrue(Advapi32.INSTANCE.OpenProcessToken(processHandle, - WinNT.TOKEN_DUPLICATE | WinNT.TOKEN_QUERY, hExistingToken)); - assertTrue(Advapi32.INSTANCE.DuplicateTokenEx(hExistingToken.getValue(), - WinNT.GENERIC_READ, null, SECURITY_IMPERSONATION_LEVEL.SecurityAnonymous, - TOKEN_TYPE.TokenPrimary, phNewToken)); - assertTrue(Kernel32.INSTANCE.CloseHandle(phNewToken.getValue())); - assertTrue(Kernel32.INSTANCE.CloseHandle(hExistingToken.getValue())); + try { + HANDLE processHandle = Kernel32.INSTANCE.GetCurrentProcess(); + assertTrue(Advapi32.INSTANCE.OpenProcessToken(processHandle, + WinNT.TOKEN_DUPLICATE | WinNT.TOKEN_QUERY, hExistingToken)); + assertTrue(Advapi32.INSTANCE.DuplicateTokenEx(hExistingToken.getValue(), + WinNT.GENERIC_READ, null, SECURITY_IMPERSONATION_LEVEL.SecurityAnonymous, + TOKEN_TYPE.TokenPrimary, phNewToken)); + } finally { + Kernel32Util.closeHandleRefs(phNewToken, hExistingToken); + } } public void testGetTokenOwnerInformation() { HANDLEByReference phToken = new HANDLEByReference(); - HANDLE processHandle = Kernel32.INSTANCE.GetCurrentProcess(); - assertTrue(Advapi32.INSTANCE.OpenProcessToken(processHandle, - WinNT.TOKEN_DUPLICATE | WinNT.TOKEN_QUERY, phToken)); - IntByReference tokenInformationLength = new IntByReference(); - assertFalse(Advapi32.INSTANCE.GetTokenInformation(phToken.getValue(), - WinNT.TOKEN_INFORMATION_CLASS.TokenOwner, null, 0, tokenInformationLength)); - assertEquals(W32Errors.ERROR_INSUFFICIENT_BUFFER, Kernel32.INSTANCE.GetLastError()); - WinNT.TOKEN_OWNER owner = new WinNT.TOKEN_OWNER(tokenInformationLength.getValue()); - assertTrue(Advapi32.INSTANCE.GetTokenInformation(phToken.getValue(), - WinNT.TOKEN_INFORMATION_CLASS.TokenOwner, owner, - tokenInformationLength.getValue(), tokenInformationLength)); - assertTrue(tokenInformationLength.getValue() > 0); - assertTrue(Advapi32.INSTANCE.IsValidSid(owner.Owner)); - int sidLength = Advapi32.INSTANCE.GetLengthSid(owner.Owner); - assertTrue(sidLength < tokenInformationLength.getValue()); - assertTrue(sidLength > 0); - // System.out.println(Advapi32Util.convertSidToStringSid(owner.Owner)); - assertTrue(Kernel32.INSTANCE.CloseHandle(phToken.getValue())); + try { + HANDLE processHandle = Kernel32.INSTANCE.GetCurrentProcess(); + assertTrue(Advapi32.INSTANCE.OpenProcessToken(processHandle, + WinNT.TOKEN_DUPLICATE | WinNT.TOKEN_QUERY, phToken)); + IntByReference tokenInformationLength = new IntByReference(); + assertFalse(Advapi32.INSTANCE.GetTokenInformation(phToken.getValue(), + WinNT.TOKEN_INFORMATION_CLASS.TokenOwner, null, 0, tokenInformationLength)); + assertEquals(W32Errors.ERROR_INSUFFICIENT_BUFFER, Kernel32.INSTANCE.GetLastError()); + WinNT.TOKEN_OWNER owner = new WinNT.TOKEN_OWNER(tokenInformationLength.getValue()); + assertTrue(Advapi32.INSTANCE.GetTokenInformation(phToken.getValue(), + WinNT.TOKEN_INFORMATION_CLASS.TokenOwner, owner, + tokenInformationLength.getValue(), tokenInformationLength)); + assertTrue(tokenInformationLength.getValue() > 0); + assertTrue(Advapi32.INSTANCE.IsValidSid(owner.Owner)); + int sidLength = Advapi32.INSTANCE.GetLengthSid(owner.Owner); + assertTrue(sidLength < tokenInformationLength.getValue()); + assertTrue(sidLength > 0); + // System.out.println(Advapi32Util.convertSidToStringSid(owner.Owner)); + } finally { + Kernel32Util.closeHandleRef(phToken); + } } public void testGetTokenUserInformation() { HANDLEByReference phToken = new HANDLEByReference(); - HANDLE processHandle = Kernel32.INSTANCE.GetCurrentProcess(); - assertTrue(Advapi32.INSTANCE.OpenProcessToken(processHandle, - WinNT.TOKEN_DUPLICATE | WinNT.TOKEN_QUERY, phToken)); - IntByReference tokenInformationLength = new IntByReference(); - assertFalse(Advapi32.INSTANCE.GetTokenInformation(phToken.getValue(), - WinNT.TOKEN_INFORMATION_CLASS.TokenUser, null, 0, tokenInformationLength)); - assertEquals(W32Errors.ERROR_INSUFFICIENT_BUFFER, Kernel32.INSTANCE.GetLastError()); - WinNT.TOKEN_USER user = new WinNT.TOKEN_USER(tokenInformationLength.getValue()); - assertTrue(Advapi32.INSTANCE.GetTokenInformation(phToken.getValue(), - WinNT.TOKEN_INFORMATION_CLASS.TokenUser, user, - tokenInformationLength.getValue(), tokenInformationLength)); - assertTrue(tokenInformationLength.getValue() > 0); - assertTrue(Advapi32.INSTANCE.IsValidSid(user.User.Sid)); - int sidLength = Advapi32.INSTANCE.GetLengthSid(user.User.Sid); - assertTrue(sidLength > 0); - assertTrue(sidLength < tokenInformationLength.getValue()); - // System.out.println(Advapi32Util.convertSidToStringSid(user.User.Sid)); - assertTrue(Kernel32.INSTANCE.CloseHandle(phToken.getValue())); + try { + HANDLE processHandle = Kernel32.INSTANCE.GetCurrentProcess(); + assertTrue(Advapi32.INSTANCE.OpenProcessToken(processHandle, + WinNT.TOKEN_DUPLICATE | WinNT.TOKEN_QUERY, phToken)); + IntByReference tokenInformationLength = new IntByReference(); + assertFalse(Advapi32.INSTANCE.GetTokenInformation(phToken.getValue(), + WinNT.TOKEN_INFORMATION_CLASS.TokenUser, null, 0, tokenInformationLength)); + assertEquals(W32Errors.ERROR_INSUFFICIENT_BUFFER, Kernel32.INSTANCE.GetLastError()); + WinNT.TOKEN_USER user = new WinNT.TOKEN_USER(tokenInformationLength.getValue()); + assertTrue(Advapi32.INSTANCE.GetTokenInformation(phToken.getValue(), + WinNT.TOKEN_INFORMATION_CLASS.TokenUser, user, + tokenInformationLength.getValue(), tokenInformationLength)); + assertTrue(tokenInformationLength.getValue() > 0); + assertTrue(Advapi32.INSTANCE.IsValidSid(user.User.Sid)); + int sidLength = Advapi32.INSTANCE.GetLengthSid(user.User.Sid); + assertTrue(sidLength > 0); + assertTrue(sidLength < tokenInformationLength.getValue()); + // System.out.println(Advapi32Util.convertSidToStringSid(user.User.Sid)); + } finally { + Kernel32Util.closeHandleRef(phToken); + } } public void testGetTokenGroupsInformation() { HANDLEByReference phToken = new HANDLEByReference(); - HANDLE processHandle = Kernel32.INSTANCE.GetCurrentProcess(); - assertTrue(Advapi32.INSTANCE.OpenProcessToken(processHandle, - WinNT.TOKEN_DUPLICATE | WinNT.TOKEN_QUERY, phToken)); - IntByReference tokenInformationLength = new IntByReference(); - assertFalse(Advapi32.INSTANCE.GetTokenInformation(phToken.getValue(), - WinNT.TOKEN_INFORMATION_CLASS.TokenGroups, null, 0, tokenInformationLength)); - assertEquals(W32Errors.ERROR_INSUFFICIENT_BUFFER, Kernel32.INSTANCE.GetLastError()); - WinNT.TOKEN_GROUPS groups = new WinNT.TOKEN_GROUPS(tokenInformationLength.getValue()); - assertTrue(Advapi32.INSTANCE.GetTokenInformation(phToken.getValue(), - WinNT.TOKEN_INFORMATION_CLASS.TokenGroups, groups, - tokenInformationLength.getValue(), tokenInformationLength)); - assertTrue(tokenInformationLength.getValue() > 0); - assertTrue(groups.GroupCount > 0); - for (SID_AND_ATTRIBUTES sidAndAttribute : groups.getGroups()) { - assertTrue(Advapi32.INSTANCE.IsValidSid(sidAndAttribute.Sid)); - // System.out.println(Advapi32Util.convertSidToStringSid(sidAndAttribute.Sid)); + try { + HANDLE processHandle = Kernel32.INSTANCE.GetCurrentProcess(); + assertTrue(Advapi32.INSTANCE.OpenProcessToken(processHandle, + WinNT.TOKEN_DUPLICATE | WinNT.TOKEN_QUERY, phToken)); + IntByReference tokenInformationLength = new IntByReference(); + assertFalse(Advapi32.INSTANCE.GetTokenInformation(phToken.getValue(), + WinNT.TOKEN_INFORMATION_CLASS.TokenGroups, null, 0, tokenInformationLength)); + assertEquals(W32Errors.ERROR_INSUFFICIENT_BUFFER, Kernel32.INSTANCE.GetLastError()); + WinNT.TOKEN_GROUPS groups = new WinNT.TOKEN_GROUPS(tokenInformationLength.getValue()); + assertTrue(Advapi32.INSTANCE.GetTokenInformation(phToken.getValue(), + WinNT.TOKEN_INFORMATION_CLASS.TokenGroups, groups, + tokenInformationLength.getValue(), tokenInformationLength)); + assertTrue(tokenInformationLength.getValue() > 0); + assertTrue(groups.GroupCount > 0); + for (SID_AND_ATTRIBUTES sidAndAttribute : groups.getGroups()) { + assertTrue(Advapi32.INSTANCE.IsValidSid(sidAndAttribute.Sid)); + // System.out.println(Advapi32Util.convertSidToStringSid(sidAndAttribute.Sid)); + } + } finally { + Kernel32Util.closeHandleRef(phToken); } - assertTrue(Kernel32.INSTANCE.CloseHandle(phToken.getValue())); } public void testImpersonateLoggedOnUser() { USER_INFO_1 userInfo = new USER_INFO_1(); - userInfo.usri1_name = new WString("JNAAdvapi32TestImp"); - userInfo.usri1_password = new WString("!JNAP$$Wrd0"); + userInfo.usri1_name = "JNAAdvapi32TestImp"; + userInfo.usri1_password = "!JNAP$$Wrd0"; userInfo.usri1_priv = LMAccess.USER_PRIV_USER; // ignore test if not able to add user (need to be administrator to do this). if (LMErr.NERR_Success != Netapi32.INSTANCE.NetUserAdd(null, 1, userInfo, null)) { @@ -372,8 +473,9 @@ assertTrue(Advapi32.INSTANCE.ImpersonateLoggedOnUser(phUser.getValue())); assertTrue(Advapi32.INSTANCE.RevertToSelf()); } finally { - if (phUser.getValue() != WinBase.INVALID_HANDLE_VALUE) { - Kernel32.INSTANCE.CloseHandle(phUser.getValue()); + HANDLE hUser = phUser.getValue(); + if (!WinBase.INVALID_HANDLE_VALUE.equals(hUser)) { + Kernel32Util.closeHandle(hUser); } } } finally { @@ -565,26 +667,234 @@ public void testIsWellKnownSid() { String sidString = EVERYONE; PSIDByReference sid = new PSIDByReference(); - assertTrue(Advapi32.INSTANCE.ConvertStringSidToSid(sidString, sid)); - assertTrue(Advapi32.INSTANCE.IsWellKnownSid(sid.getValue(), - WELL_KNOWN_SID_TYPE.WinWorldSid)); - assertFalse(Advapi32.INSTANCE.IsWellKnownSid(sid.getValue(), - WELL_KNOWN_SID_TYPE.WinAccountAdministratorSid)); + assertTrue("sid conversion failed", Advapi32.INSTANCE.ConvertStringSidToSid(sidString, sid)); + + PSID value = sid.getValue(); + try { + assertTrue("Not a world sid", Advapi32.INSTANCE.IsWellKnownSid(value, WELL_KNOWN_SID_TYPE.WinWorldSid)); + assertFalse("Unexpected admin sid", Advapi32.INSTANCE.IsWellKnownSid(value, WELL_KNOWN_SID_TYPE.WinAccountAdministratorSid)); + } finally { + Kernel32Util.freeLocalMemory(value.getPointer()); + } } public void testCreateWellKnownSid() { PSID pSid = new PSID(WinNT.SECURITY_MAX_SID_SIZE); IntByReference cbSid = new IntByReference(WinNT.SECURITY_MAX_SID_SIZE); - assertTrue(Advapi32.INSTANCE.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinWorldSid, - null, pSid, cbSid)); - assertTrue(Advapi32.INSTANCE.IsWellKnownSid(pSid, - WELL_KNOWN_SID_TYPE.WinWorldSid)); - assertTrue(cbSid.getValue() <= WinNT.SECURITY_MAX_SID_SIZE); + assertTrue("Failed to create well-known SID", + Advapi32.INSTANCE.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinWorldSid, null, pSid, cbSid)); + assertTrue("Not recognized as well-known SID", + Advapi32.INSTANCE.IsWellKnownSid(pSid, WELL_KNOWN_SID_TYPE.WinWorldSid)); + assertTrue("Invalid SID size", cbSid.getValue() <= WinNT.SECURITY_MAX_SID_SIZE); PointerByReference convertedSidStringPtr = new PointerByReference(); - assertTrue(Advapi32.INSTANCE.ConvertSidToStringSid( - pSid, convertedSidStringPtr)); - String convertedSidString = convertedSidStringPtr.getValue().getWideString(0); - assertEquals(EVERYONE, convertedSidString); + assertTrue("Failed to convert SID", Advapi32.INSTANCE.ConvertSidToStringSid(pSid, convertedSidStringPtr)); + + Pointer conv = convertedSidStringPtr.getValue(); + try { + String convertedSidString = conv.getWideString(0); + assertEquals("Mismatched SID string", EVERYONE, convertedSidString); + } finally { + Kernel32Util.freeLocalMemory(conv); + } + } + + public void testInitializeSecurityDescriptor() { + SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR(64 * 1024); + assertTrue(Advapi32.INSTANCE.InitializeSecurityDescriptor(sd, WinNT.SECURITY_DESCRIPTOR_REVISION)); + } + + public void testSetGetSecurityDescriptorControl() { + SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR(64 * 1024); + assertTrue(Advapi32.INSTANCE.InitializeSecurityDescriptor(sd, WinNT.SECURITY_DESCRIPTOR_REVISION)); + assertTrue(Advapi32.INSTANCE.SetSecurityDescriptorControl(sd, (short)WinNT.SE_DACL_PROTECTED, (short)WinNT.SE_DACL_PROTECTED)); + ShortByReference pControl = new ShortByReference(); + IntByReference lpdwRevision = new IntByReference(); + assertTrue(Advapi32.INSTANCE.GetSecurityDescriptorControl(sd, pControl, lpdwRevision)); + assertTrue(pControl.getValue() == WinNT.SE_DACL_PROTECTED); + assertTrue(lpdwRevision.getValue() == WinNT.SECURITY_DESCRIPTOR_REVISION); + } + + public void testSetGetSecurityDescriptorOwner() { + SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR(64 * 1024); + assertTrue(Advapi32.INSTANCE.InitializeSecurityDescriptor(sd, WinNT.SECURITY_DESCRIPTOR_REVISION)); + + PSID pSidPut = new PSID(WinNT.SECURITY_MAX_SID_SIZE); + IntByReference cbSid = new IntByReference(WinNT.SECURITY_MAX_SID_SIZE); + assertTrue("Failed to create well-known SID", + Advapi32.INSTANCE.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, null, pSidPut, cbSid)); + + assertTrue(Advapi32.INSTANCE.SetSecurityDescriptorOwner(sd, pSidPut, true)); + + BOOLByReference lpbOwnerDefaulted = new BOOLByReference(); + PSIDByReference prSd = new PSIDByReference(); + assertTrue(Advapi32.INSTANCE.GetSecurityDescriptorOwner(sd, prSd, lpbOwnerDefaulted)); + + PSID pSidGet = prSd.getValue(); + assertTrue(Advapi32.INSTANCE.EqualSid(pSidPut, pSidGet)); + } + + public void testSetGetSecurityDescriptorGroup() { + SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR(64 * 1024); + assertTrue(Advapi32.INSTANCE.InitializeSecurityDescriptor(sd, WinNT.SECURITY_DESCRIPTOR_REVISION)); + + PSID pSidPut = new PSID(WinNT.SECURITY_MAX_SID_SIZE); + IntByReference cbSid = new IntByReference(WinNT.SECURITY_MAX_SID_SIZE); + assertTrue("Failed to create well-known SID", + Advapi32.INSTANCE.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, null, pSidPut, cbSid)); + + assertTrue(Advapi32.INSTANCE.SetSecurityDescriptorGroup(sd, pSidPut, true)); + + BOOLByReference lpbOwnerDefaulted = new BOOLByReference(); + PSIDByReference prSd = new PSIDByReference(); + assertTrue(Advapi32.INSTANCE.GetSecurityDescriptorGroup(sd, prSd, lpbOwnerDefaulted)); + + PSID pSidGet = prSd.getValue(); + assertTrue(Advapi32.INSTANCE.EqualSid(pSidPut, pSidGet)); + } + + public void testSetGetSecurityDescriptorDacl() throws IOException { + SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR(64 * 1024); + assertTrue(Advapi32.INSTANCE.InitializeSecurityDescriptor(sd, WinNT.SECURITY_DESCRIPTOR_REVISION)); + + ACL pAcl; + int cbAcl = 0; + PSID pSid = new PSID(WinNT.SECURITY_MAX_SID_SIZE); + IntByReference cbSid = new IntByReference(WinNT.SECURITY_MAX_SID_SIZE); + assertTrue("Failed to create well-known SID", + Advapi32.INSTANCE.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, null, pSid, cbSid)); + + int sidLength = Advapi32.INSTANCE.GetLengthSid(pSid); + cbAcl = Native.getNativeSize(ACL.class, null); + cbAcl += Native.getNativeSize(ACCESS_ALLOWED_ACE.class, null); + cbAcl += (sidLength - DWORD.SIZE); + cbAcl = Advapi32Util.alignOnDWORD(cbAcl); + pAcl = new ACL(cbAcl); + assertTrue(Advapi32.INSTANCE.InitializeAcl(pAcl, cbAcl, WinNT.ACL_REVISION)); + assertTrue(Advapi32.INSTANCE.AddAccessAllowedAce(pAcl, WinNT.ACL_REVISION, WinNT.STANDARD_RIGHTS_ALL, pSid)); + assertTrue(Advapi32.INSTANCE.SetSecurityDescriptorDacl(sd, true, pAcl, false)); + BOOLByReference lpbDaclPresent = new BOOLByReference(); + BOOLByReference lpbDaclDefaulted = new BOOLByReference(); + PACLByReference pDacl = new PACLByReference(); + assertTrue(Advapi32.INSTANCE.GetSecurityDescriptorDacl(sd, lpbDaclPresent, pDacl, lpbDaclDefaulted)); + ACL pAclGet = pDacl.getValue(); + assertEquals(new BOOL(true), lpbDaclPresent.getValue()); + assertEquals(new BOOL(false), lpbDaclDefaulted.getValue()); + assertEquals(1, pAclGet.AceCount); + assertEquals(WinNT.ACL_REVISION, pAclGet.AclRevision); + } + + public void testInitializeAcl() throws IOException { + ACL pAcl; + int cbAcl = 0; + PSID pSid = new PSID(WinNT.SECURITY_MAX_SID_SIZE); + IntByReference cbSid = new IntByReference(WinNT.SECURITY_MAX_SID_SIZE); + assertTrue("Failed to create well-known SID", + Advapi32.INSTANCE.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, null, pSid, cbSid)); + + int sidLength = Advapi32.INSTANCE.GetLengthSid(pSid); + cbAcl = Native.getNativeSize(ACL.class, null); + cbAcl += Native.getNativeSize(ACCESS_ALLOWED_ACE.class, null); + cbAcl += (sidLength - DWORD.SIZE); + cbAcl = Advapi32Util.alignOnDWORD(cbAcl); + pAcl = new ACL(cbAcl); + assertTrue(Advapi32.INSTANCE.InitializeAcl(pAcl, cbAcl, WinNT.ACL_REVISION)); + } + + public void testGetAce() throws IOException { + ACL pAcl; + int cbAcl = 0; + PSID pSid = new PSID(WinNT.SECURITY_MAX_SID_SIZE); + IntByReference cbSid = new IntByReference(WinNT.SECURITY_MAX_SID_SIZE); + assertTrue("Failed to create well-known SID", + Advapi32.INSTANCE.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, null, pSid, cbSid)); + + int sidLength = Advapi32.INSTANCE.GetLengthSid(pSid); + cbAcl = Native.getNativeSize(ACL.class, null); + cbAcl += Native.getNativeSize(ACCESS_ALLOWED_ACE.class, null); + cbAcl += (sidLength - DWORD.SIZE); + cbAcl = Advapi32Util.alignOnDWORD(cbAcl); + pAcl = new ACL(cbAcl); + assertTrue(Advapi32.INSTANCE.InitializeAcl(pAcl, cbAcl, WinNT.ACL_REVISION)); + assertTrue(Advapi32.INSTANCE.AddAccessAllowedAce(pAcl, WinNT.ACL_REVISION, WinNT.STANDARD_RIGHTS_ALL, pSid)); + + PointerByReference pAce = new PointerByReference(new Memory(16)); + assertTrue(Advapi32.INSTANCE.GetAce(pAcl, 0, pAce)); + ACCESS_ALLOWED_ACE pAceGet = new ACCESS_ALLOWED_ACE(pAce.getValue()); + assertTrue(pAceGet.Mask == WinNT.STANDARD_RIGHTS_ALL); + assertTrue(Advapi32.INSTANCE.EqualSid(pAceGet.psid, pSid)); + } + + public void testAddAce() throws IOException { + ACL pAcl; + int cbAcl = 0; + PSID pSid = new PSID(WinNT.SECURITY_MAX_SID_SIZE); + IntByReference cbSid = new IntByReference(WinNT.SECURITY_MAX_SID_SIZE); + assertTrue("Failed to create well-known SID", + Advapi32.INSTANCE.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, null, pSid, cbSid)); + + int sidLength = Advapi32.INSTANCE.GetLengthSid(pSid); + cbAcl = Native.getNativeSize(ACL.class, null); + cbAcl += Advapi32Util.getAceSize(sidLength); + cbAcl = Advapi32Util.alignOnDWORD(cbAcl); + pAcl = new ACL(cbAcl); + ACCESS_ALLOWED_ACE pace = new ACCESS_ALLOWED_ACE(WinNT.STANDARD_RIGHTS_ALL, + WinNT.INHERITED_ACE, + pSid); + + assertTrue(Advapi32.INSTANCE.InitializeAcl(pAcl, cbAcl, WinNT.ACL_REVISION)); + assertTrue(Advapi32.INSTANCE.AddAce(pAcl, WinNT.ACL_REVISION, WinNT.MAXDWORD, pace.getPointer(), pace.size())); + + PointerByReference pAce = new PointerByReference(new Memory(16)); + assertTrue(Advapi32.INSTANCE.GetAce(pAcl, 0, pAce)); + ACCESS_ALLOWED_ACE pAceGet = new ACCESS_ALLOWED_ACE(pAce.getValue()); + assertTrue(pAceGet.Mask == WinNT.STANDARD_RIGHTS_ALL); + assertTrue(Advapi32.INSTANCE.EqualSid(pAceGet.psid, pSid)); + } + + public void testAddAccessAllowedAce() throws IOException { + ACL pAcl; + int cbAcl = 0; + PSID pSid = new PSID(WinNT.SECURITY_MAX_SID_SIZE); + IntByReference cbSid = new IntByReference(WinNT.SECURITY_MAX_SID_SIZE); + assertTrue("Failed to create well-known SID", + Advapi32.INSTANCE.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, null, pSid, cbSid)); + + int sidLength = Advapi32.INSTANCE.GetLengthSid(pSid); + cbAcl = Native.getNativeSize(ACL.class, null); + cbAcl += Advapi32Util.getAceSize(sidLength); + cbAcl = Advapi32Util.alignOnDWORD(cbAcl); + pAcl = new ACL(cbAcl); + assertTrue(Advapi32.INSTANCE.InitializeAcl(pAcl, cbAcl, WinNT.ACL_REVISION)); + assertTrue(Advapi32.INSTANCE.AddAccessAllowedAce(pAcl, WinNT.ACL_REVISION, WinNT.STANDARD_RIGHTS_ALL, pSid)); + + PointerByReference pAce = new PointerByReference(new Memory(16)); + assertTrue(Advapi32.INSTANCE.GetAce(pAcl, 0, pAce)); + ACCESS_ALLOWED_ACE pAceGet = new ACCESS_ALLOWED_ACE(pAce.getValue()); + assertTrue(pAceGet.Mask == WinNT.STANDARD_RIGHTS_ALL); + assertTrue(Advapi32.INSTANCE.EqualSid(pAceGet.psid, pSid)); + } + + public void testAddAccessAllowedAceEx() throws IOException { + ACL pAcl; + int cbAcl = 0; + PSID pSid = new PSID(WinNT.SECURITY_MAX_SID_SIZE); + IntByReference cbSid = new IntByReference(WinNT.SECURITY_MAX_SID_SIZE); + assertTrue("Failed to create well-known SID", + Advapi32.INSTANCE.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, null, pSid, cbSid)); + + int sidLength = Advapi32.INSTANCE.GetLengthSid(pSid); + cbAcl = Native.getNativeSize(ACL.class, null); + cbAcl += Advapi32Util.getAceSize(sidLength); + cbAcl = Advapi32Util.alignOnDWORD(cbAcl); + pAcl = new ACL(cbAcl); + assertTrue(Advapi32.INSTANCE.InitializeAcl(pAcl, cbAcl, WinNT.ACL_REVISION)); + assertTrue(Advapi32.INSTANCE.AddAccessAllowedAceEx(pAcl, WinNT.ACL_REVISION, WinNT.INHERIT_ONLY_ACE, WinNT.STANDARD_RIGHTS_ALL, pSid)); + + PointerByReference pAce = new PointerByReference(new Memory(16)); + assertTrue(Advapi32.INSTANCE.GetAce(pAcl, 0, pAce)); + ACCESS_ALLOWED_ACE pAceGet = new ACCESS_ALLOWED_ACE(pAce.getValue()); + assertTrue(pAceGet.Mask == WinNT.STANDARD_RIGHTS_ALL); + assertTrue(Advapi32.INSTANCE.EqualSid(pAceGet.psid, pSid)); } public void testOpenEventLog() { @@ -853,12 +1163,14 @@ HANDLE processHandle = Kernel32.INSTANCE.GetCurrentProcess(); assertTrue(Advapi32.INSTANCE.OpenProcessToken(processHandle, WinNT.TOKEN_DUPLICATE | WinNT.TOKEN_QUERY, hToken)); - - assertFalse(Advapi32.INSTANCE.CreateProcessAsUser(hToken.getValue(), null, "InvalidCmdLine.jna", - null, null, false, 0, null, null, new WinBase.STARTUPINFO(), - new WinBase.PROCESS_INFORMATION())); - assertEquals(W32Errors.ERROR_FILE_NOT_FOUND, Kernel32.INSTANCE.GetLastError()); - assertTrue(Kernel32.INSTANCE.CloseHandle(hToken.getValue())); + try { + assertFalse(Advapi32.INSTANCE.CreateProcessAsUser(hToken.getValue(), null, "InvalidCmdLine.jna", + null, null, false, 0, null, null, new WinBase.STARTUPINFO(), + new WinBase.PROCESS_INFORMATION())); + assertEquals(W32Errors.ERROR_FILE_NOT_FOUND, Kernel32.INSTANCE.GetLastError()); + } finally { + Kernel32Util.closeHandleRef(hToken); + } } /** @@ -885,27 +1197,30 @@ assertTrue(Advapi32.INSTANCE.OpenProcessToken(Kernel32.INSTANCE.GetCurrentProcess(), WinNT.TOKEN_ADJUST_PRIVILEGES | WinNT.TOKEN_QUERY, hToken)); - // Find an already enabled privilege - TOKEN_PRIVILEGES tp = new TOKEN_PRIVILEGES(1024); - IntByReference returnLength = new IntByReference(); - assertTrue(Advapi32.INSTANCE.GetTokenInformation(hToken.getValue(), WinNT.TOKEN_INFORMATION_CLASS.TokenPrivileges, - tp, tp.size(), returnLength)); - assertTrue(tp.PrivilegeCount.intValue() > 0); - - WinNT.LUID luid = null; - for (int i=0; i 0) { - luid = tp.Privileges[i].Luid; - } + try { + // Find an already enabled privilege + TOKEN_PRIVILEGES tp = new TOKEN_PRIVILEGES(1024); + IntByReference returnLength = new IntByReference(); + assertTrue(Advapi32.INSTANCE.GetTokenInformation(hToken.getValue(), WinNT.TOKEN_INFORMATION_CLASS.TokenPrivileges, + tp, tp.size(), returnLength)); + assertTrue(tp.PrivilegeCount.intValue() > 0); + + WinNT.LUID luid = null; + for (int i=0; i 0) { + luid = tp.Privileges[i].Luid; + } + } + assertTrue(luid != null); + + // Re-enable it. That should succeed. + tp = new WinNT.TOKEN_PRIVILEGES(1); + tp.Privileges[0] = new WinNT.LUID_AND_ATTRIBUTES(luid, new DWORD(WinNT.SE_PRIVILEGE_ENABLED)); + + assertTrue(Advapi32.INSTANCE.AdjustTokenPrivileges(hToken.getValue(), false, tp, 0, null, null)); + } finally { + Kernel32Util.closeHandleRef(hToken); } - assertTrue(luid != null); - - // Re-enable it. That should succeed. - tp = new WinNT.TOKEN_PRIVILEGES(1); - tp.Privileges[0] = new WinNT.LUID_AND_ATTRIBUTES(luid, new DWORD(WinNT.SE_PRIVILEGE_ENABLED)); - - assertTrue(Advapi32.INSTANCE.AdjustTokenPrivileges(hToken.getValue(), false, tp, 0, null, null)); - assertTrue(Kernel32.INSTANCE.CloseHandle(hToken.getValue())); } public void testImpersonateSelf() { @@ -913,10 +1228,38 @@ assertTrue(Advapi32.INSTANCE.RevertToSelf()); } + public void testGetSetFileSecurityNoSACL() throws Exception { + int infoType = OWNER_SECURITY_INFORMATION + | GROUP_SECURITY_INFORMATION + | DACL_SECURITY_INFORMATION; - public void testGetNamedSecurityInfoForFileNoSACL() throws Exception { - // create a temp file + int memSize = 64 * 1024; + Memory memorySecurity = new Memory(memSize); + IntByReference sizeNeeded = new IntByReference(0); + // create a temp file File file = createTempFile(); + String filePath = file.getAbsolutePath(); + + try { + + assertEquals("GetFileSecurity(" + filePath + ")", true, + Advapi32.INSTANCE.GetFileSecurity( + filePath, + infoType, + memorySecurity, + memSize, + sizeNeeded)); + assertEquals("SetFileSecurity(" + filePath + ")", true, + Advapi32.INSTANCE.SetFileSecurity( + filePath, + infoType, + memorySecurity)); + } finally { + file.delete(); + } + } + + public void testGetSetSecurityInfoNoSACL() throws Exception { int infoType = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION; @@ -925,104 +1268,273 @@ PointerByReference ppsidGroup = new PointerByReference(); PointerByReference ppDacl = new PointerByReference(); PointerByReference ppSecurityDescriptor = new PointerByReference(); + // create a temp file + File file = createTempFile(); + String filePath = file.getAbsolutePath(); - assertEquals(Advapi32.INSTANCE.GetNamedSecurityInfo( - file.getAbsolutePath(), - AccCtrl.SE_OBJECT_TYPE.SE_FILE_OBJECT, - infoType, - ppsidOwner, - ppsidGroup, - ppDacl, - null, - ppSecurityDescriptor), 0); + HANDLE hFile = Kernel32.INSTANCE.CreateFile( + filePath, + WinNT.GENERIC_ALL | WinNT.WRITE_OWNER | WinNT.WRITE_DAC, + WinNT.FILE_SHARE_READ, + new WinBase.SECURITY_ATTRIBUTES(), + WinNT.OPEN_EXISTING, + WinNT.FILE_ATTRIBUTE_NORMAL, + null); + assertFalse("Failed to create file handle: " + filePath, WinBase.INVALID_HANDLE_VALUE.equals(hFile)); - Kernel32.INSTANCE.LocalFree(ppSecurityDescriptor.getValue()); - file.delete(); - } + try { + try { - public void testGetNamedSecurityInfoForFileWithSACL() throws Exception { + assertEquals("GetSecurityInfo(" + filePath + ")", 0, + Advapi32.INSTANCE.GetSecurityInfo( + hFile, + AccCtrl.SE_OBJECT_TYPE.SE_FILE_OBJECT, + infoType, + ppsidOwner, + ppsidGroup, + ppDacl, + null, + ppSecurityDescriptor)); + + assertEquals("SetSecurityInfo(" + filePath + ")", 0, + Advapi32.INSTANCE.SetSecurityInfo( + hFile, + AccCtrl.SE_OBJECT_TYPE.SE_FILE_OBJECT, + infoType, + ppsidOwner.getValue(), + ppsidGroup.getValue(), + ppDacl.getValue(), + null)); + } finally { + Kernel32.INSTANCE.CloseHandle(hFile); + file.delete(); + } + } finally { + Kernel32Util.freeLocalMemory(ppSecurityDescriptor.getValue()); + } + } + public void testGetSetSecurityInfoForFileWithSACL() throws Exception { boolean impersontating = false; - WinNT.LUID pLuid = new WinNT.LUID(); - assertTrue(Advapi32.INSTANCE.LookupPrivilegeValue(null, SE_SECURITY_NAME, pLuid)); + HANDLEByReference phToken = new HANDLEByReference(); + HANDLEByReference phTokenDuplicate = new HANDLEByReference(); + try { + // open thread or process token, elevate + if (!Advapi32.INSTANCE.OpenThreadToken( + Kernel32.INSTANCE.GetCurrentThread(), + TOKEN_ADJUST_PRIVILEGES, + false, + phToken)) + { + assertEquals(W32Errors.ERROR_NO_TOKEN, Kernel32.INSTANCE.GetLastError()); + // OpenThreadToken may fail with W32Errors.ERROR_NO_TOKEN if current thread is anonymous. When this happens, + // we need to open the process token to duplicate it, then set our thread token. + assertTrue(Advapi32.INSTANCE.OpenProcessToken(Kernel32.INSTANCE.GetCurrentProcess(), TOKEN_DUPLICATE, phToken)); + // Process token opened, now duplicate + assertTrue(Advapi32.INSTANCE.DuplicateTokenEx( + phToken.getValue(), + TOKEN_ADJUST_PRIVILEGES | TOKEN_IMPERSONATE, + null, + SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, + TOKEN_TYPE.TokenImpersonation, + phTokenDuplicate)); + // And set thread token. + assertTrue(Advapi32.INSTANCE.SetThreadToken(null, phTokenDuplicate.getValue())); + impersontating = true; + } - final HANDLEByReference phToken = new HANDLEByReference(); - final HANDLEByReference phTokenDuplicate = new HANDLEByReference(); - // open thread or process token, elevate - if (!Advapi32.INSTANCE.OpenThreadToken( - Kernel32.INSTANCE.GetCurrentThread(), - TOKEN_ADJUST_PRIVILEGES, - false, - phToken)) - { - assertEquals(W32Errors.ERROR_NO_TOKEN, Kernel32.INSTANCE.GetLastError()); - // OpenThreadToken may fail with W32Errors.ERROR_NO_TOKEN if current thread is anonymous. When this happens, - // we need to open the process token to duplicate it, then set our thread token. - assertTrue(Advapi32.INSTANCE.OpenProcessToken(Kernel32.INSTANCE.GetCurrentProcess(), TOKEN_DUPLICATE, phToken)); - // Process token opened, now duplicate - assertTrue(Advapi32.INSTANCE.DuplicateTokenEx(phToken.getValue(), - TOKEN_ADJUST_PRIVILEGES | TOKEN_IMPERSONATE, - null, - SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, - TOKEN_TYPE.TokenImpersonation, - phTokenDuplicate)); - // And set thread token. - assertTrue(Advapi32.INSTANCE.SetThreadToken(null, phTokenDuplicate.getValue())); - impersontating = true; - } + // Which token to adjust depends on whether we had to impersonate or not. + HANDLE tokenAdjust = impersontating ? phTokenDuplicate.getValue() : phToken.getValue(); - // Which token to adjust depends on whether we had to impersonate or not. - HANDLE tokenAdjust = impersontating ? phTokenDuplicate.getValue() : phToken.getValue(); + WinNT.TOKEN_PRIVILEGES tp = new WinNT.TOKEN_PRIVILEGES(1); + WinNT.LUID pLuid = new WinNT.LUID(); - WinNT.TOKEN_PRIVILEGES tp = new WinNT.TOKEN_PRIVILEGES(1); - tp.Privileges[0] = new WinNT.LUID_AND_ATTRIBUTES(pLuid, new DWORD(WinNT.SE_PRIVILEGE_ENABLED)); - assertTrue(Advapi32.INSTANCE.AdjustTokenPrivileges(tokenAdjust, false, tp, 0, null, null)); + assertTrue(Advapi32.INSTANCE.LookupPrivilegeValue(null, SE_SECURITY_NAME, pLuid)); + tp.Privileges[0] = new WinNT.LUID_AND_ATTRIBUTES(pLuid, new DWORD(WinNT.SE_PRIVILEGE_ENABLED)); + assertTrue(Advapi32.INSTANCE.AdjustTokenPrivileges(tokenAdjust, false, tp, 0, null, null)); + + assertTrue(Advapi32.INSTANCE.LookupPrivilegeValue(null, SE_RESTORE_NAME, pLuid)); + tp.Privileges[0] = new WinNT.LUID_AND_ATTRIBUTES(pLuid, new DWORD(WinNT.SE_PRIVILEGE_ENABLED)); + assertTrue(Advapi32.INSTANCE.AdjustTokenPrivileges(tokenAdjust, false, tp, 0, null, null)); + + // create a temp file + File file = createTempFile(); + int infoType = OWNER_SECURITY_INFORMATION + | GROUP_SECURITY_INFORMATION + | DACL_SECURITY_INFORMATION + | SACL_SECURITY_INFORMATION; + + PointerByReference ppsidOwner = new PointerByReference(); + PointerByReference ppsidGroup = new PointerByReference(); + PointerByReference ppDacl = new PointerByReference(); + PointerByReference ppSacl = new PointerByReference(); + PointerByReference ppSecurityDescriptor = new PointerByReference(); + String filePath = file.getAbsolutePath(); + HANDLE hFile = WinBase.INVALID_HANDLE_VALUE; - // create a temp file - File file = createTempFile(); + try { + try { + hFile = Kernel32.INSTANCE.CreateFile( + filePath, + WinNT.ACCESS_SYSTEM_SECURITY | WinNT.GENERIC_WRITE | WinNT.WRITE_OWNER | WinNT.WRITE_DAC, + WinNT.FILE_SHARE_READ, + new WinBase.SECURITY_ATTRIBUTES(), + WinNT.OPEN_EXISTING, + WinNT.FILE_ATTRIBUTE_NORMAL, + null); + assertEquals("GetSecurityInfo(" + filePath + ")", 0, + Advapi32.INSTANCE.GetSecurityInfo( + hFile, + AccCtrl.SE_OBJECT_TYPE.SE_FILE_OBJECT, + infoType, + ppsidOwner, + ppsidGroup, + ppDacl, + ppSacl, + ppSecurityDescriptor)); + assertEquals("SetSecurityInfo(" + filePath + ")", 0, + Advapi32.INSTANCE.SetSecurityInfo( + hFile, + AccCtrl.SE_OBJECT_TYPE.SE_FILE_OBJECT, + infoType, + ppsidOwner.getValue(), + ppsidGroup.getValue(), + ppDacl.getValue(), + ppSacl.getValue())); + } finally { + if (hFile != WinBase.INVALID_HANDLE_VALUE) + Kernel32.INSTANCE.CloseHandle(hFile); + file.delete(); + } + } finally { + Kernel32Util.freeLocalMemory(ppSecurityDescriptor.getValue()); + } + if (impersontating) { + assertTrue("SetThreadToken", Advapi32.INSTANCE.SetThreadToken(null, null)); + } + else { + tp.Privileges[0] = new WinNT.LUID_AND_ATTRIBUTES(pLuid, new DWORD(0)); + assertTrue("AdjustTokenPrivileges", Advapi32.INSTANCE.AdjustTokenPrivileges(tokenAdjust, false, tp, 0, null, null)); + } + } finally { + Kernel32Util.closeHandleRefs(phToken, phTokenDuplicate); + } + } + + public void testGetNamedSecurityInfoForFileNoSACL() throws Exception { int infoType = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION - | DACL_SECURITY_INFORMATION - | SACL_SECURITY_INFORMATION; + | DACL_SECURITY_INFORMATION; PointerByReference ppsidOwner = new PointerByReference(); PointerByReference ppsidGroup = new PointerByReference(); PointerByReference ppDacl = new PointerByReference(); - PointerByReference ppSacl = new PointerByReference(); PointerByReference ppSecurityDescriptor = new PointerByReference(); - assertEquals(Advapi32.INSTANCE.GetNamedSecurityInfo( - file.getAbsolutePath(), - AccCtrl.SE_OBJECT_TYPE.SE_FILE_OBJECT, - infoType, - ppsidOwner, - ppsidGroup, - ppDacl, - ppSacl, - ppSecurityDescriptor), 0); - - // Clean up resources - Kernel32.INSTANCE.LocalFree(ppSecurityDescriptor.getValue()); - file.delete(); - if (impersontating) { - Advapi32.INSTANCE.SetThreadToken(null, null); + File file = createTempFile(); + try { + try { + assertEquals("GetNamedSecurityInfo(" + file + ")", 0, + Advapi32.INSTANCE.GetNamedSecurityInfo( + file.getAbsolutePath(), + AccCtrl.SE_OBJECT_TYPE.SE_FILE_OBJECT, + infoType, + ppsidOwner, + ppsidGroup, + ppDacl, + null, + ppSecurityDescriptor)); + } finally { + file.delete(); + } + } finally { + Kernel32Util.freeLocalMemory(ppSecurityDescriptor.getValue()); } - else { - tp.Privileges[0] = new WinNT.LUID_AND_ATTRIBUTES(pLuid, new DWORD(0)); - Advapi32.INSTANCE.AdjustTokenPrivileges(tokenAdjust, false, tp, 0, null, null); + } + + public void testGetNamedSecurityInfoForFileWithSACL() throws Exception { + + boolean impersontating = false; + WinNT.LUID pLuid = new WinNT.LUID(); + + assertTrue(Advapi32.INSTANCE.LookupPrivilegeValue(null, SE_SECURITY_NAME, pLuid)); + + HANDLEByReference phToken = new HANDLEByReference(); + HANDLEByReference phTokenDuplicate = new HANDLEByReference(); + try { + // open thread or process token, elevate + if (!Advapi32.INSTANCE.OpenThreadToken( + Kernel32.INSTANCE.GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES, false, phToken)) + { + assertEquals(W32Errors.ERROR_NO_TOKEN, Kernel32.INSTANCE.GetLastError()); + // OpenThreadToken may fail with W32Errors.ERROR_NO_TOKEN if current thread is anonymous. When this happens, + // we need to open the process token to duplicate it, then set our thread token. + assertTrue(Advapi32.INSTANCE.OpenProcessToken(Kernel32.INSTANCE.GetCurrentProcess(), TOKEN_DUPLICATE, phToken)); + // Process token opened, now duplicate + assertTrue(Advapi32.INSTANCE.DuplicateTokenEx(phToken.getValue(), + TOKEN_ADJUST_PRIVILEGES | TOKEN_IMPERSONATE, + null, + SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, + TOKEN_TYPE.TokenImpersonation, + phTokenDuplicate)); + // And set thread token. + assertTrue(Advapi32.INSTANCE.SetThreadToken(null, phTokenDuplicate.getValue())); + impersontating = true; + } + + // Which token to adjust depends on whether we had to impersonate or not. + HANDLE tokenAdjust = impersontating ? phTokenDuplicate.getValue() : phToken.getValue(); + + WinNT.TOKEN_PRIVILEGES tp = new WinNT.TOKEN_PRIVILEGES(1); + tp.Privileges[0] = new WinNT.LUID_AND_ATTRIBUTES(pLuid, new DWORD(WinNT.SE_PRIVILEGE_ENABLED)); + assertTrue(Advapi32.INSTANCE.AdjustTokenPrivileges(tokenAdjust, false, tp, 0, null, null)); + + int infoType = OWNER_SECURITY_INFORMATION + | GROUP_SECURITY_INFORMATION + | DACL_SECURITY_INFORMATION + | SACL_SECURITY_INFORMATION; + + PointerByReference ppsidOwner = new PointerByReference(); + PointerByReference ppsidGroup = new PointerByReference(); + PointerByReference ppDacl = new PointerByReference(); + PointerByReference ppSacl = new PointerByReference(); + PointerByReference ppSecurityDescriptor = new PointerByReference(); + + File file = createTempFile(); + String filePath = file.getAbsolutePath(); + try { + try { + assertEquals("GetNamedSecurityInfo(" + filePath + ")", 0, + Advapi32.INSTANCE.GetNamedSecurityInfo( + filePath, + AccCtrl.SE_OBJECT_TYPE.SE_FILE_OBJECT, + infoType, + ppsidOwner, + ppsidGroup, + ppDacl, + ppSacl, + ppSecurityDescriptor)); + } finally { + file.delete(); + } + } finally { + Kernel32Util.freeLocalMemory(ppSecurityDescriptor.getValue()); + } + if (impersontating) { + Advapi32.INSTANCE.SetThreadToken(null, null); + } + else { + tp.Privileges[0] = new WinNT.LUID_AND_ATTRIBUTES(pLuid, new DWORD(0)); + Advapi32.INSTANCE.AdjustTokenPrivileges(tokenAdjust, false, tp, 0, null, null); + } + } finally { + Kernel32Util.closeHandleRefs(phToken, phTokenDuplicate); } - if (phToken.getValue() != null) - Kernel32.INSTANCE.CloseHandle(phToken.getValue()); - if (phTokenDuplicate.getValue() != null) - Kernel32.INSTANCE.CloseHandle(phTokenDuplicate.getValue()); } public void testSetNamedSecurityInfoForFileNoSACL() throws Exception { - // create a temp file - File file = createTempFile(); - int infoType = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION; @@ -1031,168 +1543,251 @@ PointerByReference ppsidGroup = new PointerByReference(); PointerByReference ppDacl = new PointerByReference(); PointerByReference ppSecurityDescriptor = new PointerByReference(); - - assertEquals(Advapi32.INSTANCE.GetNamedSecurityInfo( - file.getAbsolutePath(), - AccCtrl.SE_OBJECT_TYPE.SE_FILE_OBJECT, - infoType, - ppsidOwner, - ppsidGroup, - ppDacl, - null, - ppSecurityDescriptor), 0); - - assertEquals(Advapi32.INSTANCE.SetNamedSecurityInfo( - file.getAbsolutePath(), - AccCtrl.SE_OBJECT_TYPE.SE_FILE_OBJECT, - infoType, - ppsidOwner.getValue(), - ppsidGroup.getValue(), - ppDacl.getValue(), - null), 0); - - Kernel32.INSTANCE.LocalFree(ppSecurityDescriptor.getValue()); - file.delete(); + // create a temp file + File file = createTempFile(); + String filePath = file.getAbsolutePath(); + try { + try { + assertEquals("GetNamedSecurityInfo(" + filePath + ")", 0, + Advapi32.INSTANCE.GetNamedSecurityInfo( + filePath, + AccCtrl.SE_OBJECT_TYPE.SE_FILE_OBJECT, + infoType, + ppsidOwner, + ppsidGroup, + ppDacl, + null, + ppSecurityDescriptor)); + assertEquals("SetNamedSecurityInfo(" + filePath + ")", 0, + Advapi32.INSTANCE.SetNamedSecurityInfo( + filePath, + AccCtrl.SE_OBJECT_TYPE.SE_FILE_OBJECT, + infoType, + ppsidOwner.getValue(), + ppsidGroup.getValue(), + ppDacl.getValue(), + null)); + } finally { + file.delete(); + } + } finally { + Kernel32Util.freeLocalMemory(ppSecurityDescriptor.getValue()); + } } public void testSetNamedSecurityInfoForFileWithSACL() throws Exception { boolean impersontating = false; - final HANDLEByReference phToken = new HANDLEByReference(); - final HANDLEByReference phTokenDuplicate = new HANDLEByReference(); - // open thread or process token, elevate - if (!Advapi32.INSTANCE.OpenThreadToken( - Kernel32.INSTANCE.GetCurrentThread(), - TOKEN_ADJUST_PRIVILEGES, - false, - phToken)) - { - assertEquals(W32Errors.ERROR_NO_TOKEN, Kernel32.INSTANCE.GetLastError()); - // OpenThreadToken may fail with W32Errors.ERROR_NO_TOKEN if current thread is anonymous. When this happens, - // we need to open the process token to duplicate it, then set our thread token. - assertTrue(Advapi32.INSTANCE.OpenProcessToken(Kernel32.INSTANCE.GetCurrentProcess(), TOKEN_DUPLICATE, phToken)); - // Process token opened, now duplicate - assertTrue(Advapi32.INSTANCE.DuplicateTokenEx( - phToken.getValue(), - TOKEN_ADJUST_PRIVILEGES | TOKEN_IMPERSONATE, - null, - SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, - TOKEN_TYPE.TokenImpersonation, - phTokenDuplicate)); - // And set thread token. - assertTrue(Advapi32.INSTANCE.SetThreadToken(null, phTokenDuplicate.getValue())); - impersontating = true; - } - - // Which token to adjust depends on whether we had to impersonate or not. - HANDLE tokenAdjust = impersontating ? phTokenDuplicate.getValue() : phToken.getValue(); - - WinNT.TOKEN_PRIVILEGES tp = new WinNT.TOKEN_PRIVILEGES(1); - WinNT.LUID pLuid = new WinNT.LUID(); - - assertTrue(Advapi32.INSTANCE.LookupPrivilegeValue(null, SE_SECURITY_NAME, pLuid)); - tp.Privileges[0] = new WinNT.LUID_AND_ATTRIBUTES(pLuid, new DWORD(WinNT.SE_PRIVILEGE_ENABLED)); - assertTrue(Advapi32.INSTANCE.AdjustTokenPrivileges(tokenAdjust, false, tp, 0, null, null)); + HANDLEByReference phToken = new HANDLEByReference(); + HANDLEByReference phTokenDuplicate = new HANDLEByReference(); + try { + // open thread or process token, elevate + if (!Advapi32.INSTANCE.OpenThreadToken( + Kernel32.INSTANCE.GetCurrentThread(), + TOKEN_ADJUST_PRIVILEGES, + false, + phToken)) + { + assertEquals(W32Errors.ERROR_NO_TOKEN, Kernel32.INSTANCE.GetLastError()); + // OpenThreadToken may fail with W32Errors.ERROR_NO_TOKEN if current thread is anonymous. When this happens, + // we need to open the process token to duplicate it, then set our thread token. + assertTrue(Advapi32.INSTANCE.OpenProcessToken(Kernel32.INSTANCE.GetCurrentProcess(), TOKEN_DUPLICATE, phToken)); + // Process token opened, now duplicate + assertTrue(Advapi32.INSTANCE.DuplicateTokenEx( + phToken.getValue(), + TOKEN_ADJUST_PRIVILEGES | TOKEN_IMPERSONATE, + null, + SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, + TOKEN_TYPE.TokenImpersonation, + phTokenDuplicate)); + // And set thread token. + assertTrue(Advapi32.INSTANCE.SetThreadToken(null, phTokenDuplicate.getValue())); + impersontating = true; + } - assertTrue(Advapi32.INSTANCE.LookupPrivilegeValue(null, SE_RESTORE_NAME, pLuid)); - tp.Privileges[0] = new WinNT.LUID_AND_ATTRIBUTES(pLuid, new DWORD(WinNT.SE_PRIVILEGE_ENABLED)); - assertTrue(Advapi32.INSTANCE.AdjustTokenPrivileges(tokenAdjust, false, tp, 0, null, null)); + // Which token to adjust depends on whether we had to impersonate or not. + HANDLE tokenAdjust = impersontating ? phTokenDuplicate.getValue() : phToken.getValue(); - // create a temp file - File file = createTempFile(); - int infoType = OWNER_SECURITY_INFORMATION - | GROUP_SECURITY_INFORMATION - | DACL_SECURITY_INFORMATION - | SACL_SECURITY_INFORMATION; - - PointerByReference ppsidOwner = new PointerByReference(); - PointerByReference ppsidGroup = new PointerByReference(); - PointerByReference ppDacl = new PointerByReference(); - PointerByReference ppSacl = new PointerByReference(); - PointerByReference ppSecurityDescriptor = new PointerByReference(); + WinNT.TOKEN_PRIVILEGES tp = new WinNT.TOKEN_PRIVILEGES(1); + WinNT.LUID pLuid = new WinNT.LUID(); - assertEquals(Advapi32.INSTANCE.GetNamedSecurityInfo( - file.getAbsolutePath(), - AccCtrl.SE_OBJECT_TYPE.SE_FILE_OBJECT, - infoType, - ppsidOwner, - ppsidGroup, - ppDacl, - ppSacl, - ppSecurityDescriptor), 0); - - // Send the DACL as a SACL - assertEquals(Advapi32.INSTANCE.SetNamedSecurityInfo( - file.getAbsolutePath(), - AccCtrl.SE_OBJECT_TYPE.SE_FILE_OBJECT, - infoType, - ppsidOwner.getValue(), - ppsidGroup.getValue(), - ppDacl.getValue(), - ppDacl.getValue()), 0); + assertTrue(Advapi32.INSTANCE.LookupPrivilegeValue(null, SE_SECURITY_NAME, pLuid)); + tp.Privileges[0] = new WinNT.LUID_AND_ATTRIBUTES(pLuid, new DWORD(WinNT.SE_PRIVILEGE_ENABLED)); + assertTrue(Advapi32.INSTANCE.AdjustTokenPrivileges(tokenAdjust, false, tp, 0, null, null)); + + assertTrue(Advapi32.INSTANCE.LookupPrivilegeValue(null, SE_RESTORE_NAME, pLuid)); + tp.Privileges[0] = new WinNT.LUID_AND_ATTRIBUTES(pLuid, new DWORD(WinNT.SE_PRIVILEGE_ENABLED)); + assertTrue(Advapi32.INSTANCE.AdjustTokenPrivileges(tokenAdjust, false, tp, 0, null, null)); + + // create a temp file + File file = createTempFile(); + int infoType = OWNER_SECURITY_INFORMATION + | GROUP_SECURITY_INFORMATION + | DACL_SECURITY_INFORMATION + | SACL_SECURITY_INFORMATION; + + PointerByReference ppsidOwner = new PointerByReference(); + PointerByReference ppsidGroup = new PointerByReference(); + PointerByReference ppDacl = new PointerByReference(); + PointerByReference ppSacl = new PointerByReference(); + PointerByReference ppSecurityDescriptor = new PointerByReference(); + String filePath = file.getAbsolutePath(); + try { + try { + assertEquals("GetNamedSecurityInfo(" + filePath + ")", 0, + Advapi32.INSTANCE.GetNamedSecurityInfo( + filePath, + AccCtrl.SE_OBJECT_TYPE.SE_FILE_OBJECT, + infoType, + ppsidOwner, + ppsidGroup, + ppDacl, + ppSacl, + ppSecurityDescriptor)); + + // Send the DACL as a SACL + assertEquals("SetNamedSecurityInfo(" + filePath + ")", 0, + Advapi32.INSTANCE.SetNamedSecurityInfo( + filePath, + AccCtrl.SE_OBJECT_TYPE.SE_FILE_OBJECT, + infoType, + ppsidOwner.getValue(), + ppsidGroup.getValue(), + ppDacl.getValue(), + ppDacl.getValue())); + } finally { + file.delete(); + } + } finally { + Kernel32Util.freeLocalMemory(ppSecurityDescriptor.getValue()); + } - // Clean up resources - Kernel32.INSTANCE.LocalFree(ppSecurityDescriptor.getValue()); - file.delete(); - if (impersontating) { - Advapi32.INSTANCE.SetThreadToken(null, null); - } - else { - tp.Privileges[0] = new WinNT.LUID_AND_ATTRIBUTES(pLuid, new DWORD(0)); - Advapi32.INSTANCE.AdjustTokenPrivileges(tokenAdjust, false, tp, 0, null, null); + if (impersontating) { + assertTrue("SetThreadToken", Advapi32.INSTANCE.SetThreadToken(null, null)); + } + else { + tp.Privileges[0] = new WinNT.LUID_AND_ATTRIBUTES(pLuid, new DWORD(0)); + assertTrue("AdjustTokenPrivileges", Advapi32.INSTANCE.AdjustTokenPrivileges(tokenAdjust, false, tp, 0, null, null)); + } + } finally { + Kernel32Util.closeHandleRefs(phToken, phTokenDuplicate); } - if (phToken.getValue() != null) - Kernel32.INSTANCE.CloseHandle(phToken.getValue()); - if (phTokenDuplicate.getValue() != null) - Kernel32.INSTANCE.CloseHandle(phTokenDuplicate.getValue()); } public void testGetSecurityDescriptorLength() throws Exception { - // create a temp file - File file = createTempFile(); int infoType = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION; PointerByReference ppSecurityDescriptor = new PointerByReference(); - assertEquals(Advapi32.INSTANCE.GetNamedSecurityInfo( - file.getAbsolutePath(), - AccCtrl.SE_OBJECT_TYPE.SE_FILE_OBJECT, - infoType, - null, - null, - null, - null, - ppSecurityDescriptor), 0); - - assertTrue(Advapi32.INSTANCE.GetSecurityDescriptorLength(ppSecurityDescriptor.getValue()) > 0); - Kernel32.INSTANCE.LocalFree(ppSecurityDescriptor.getValue()); - file.delete(); + File file = createTempFile(); + try { + try { + assertEquals("GetNamedSecurityInfo(" + file + ")", 0, + Advapi32.INSTANCE.GetNamedSecurityInfo( + file.getAbsolutePath(), + AccCtrl.SE_OBJECT_TYPE.SE_FILE_OBJECT, + infoType, + null, + null, + null, + null, + ppSecurityDescriptor)); + + assertTrue("GetSecurityDescriptorLength(" + file + ")", + Advapi32.INSTANCE.GetSecurityDescriptorLength(ppSecurityDescriptor.getValue()) > 0); + } finally { + file.delete(); + } + } finally { + Kernel32Util.freeLocalMemory(ppSecurityDescriptor.getValue()); + } } public void testIsValidSecurityDescriptor() throws Exception { - // create a temp file - File file = createTempFile(); int infoType = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION; PointerByReference ppSecurityDescriptor = new PointerByReference(); - assertEquals(Advapi32.INSTANCE.GetNamedSecurityInfo( - file.getAbsolutePath(), - AccCtrl.SE_OBJECT_TYPE.SE_FILE_OBJECT, - infoType, - null, - null, - null, - null, - ppSecurityDescriptor), 0); + File file = createTempFile(); + try { + try { + assertEquals("GetNamedSecurityInfo(" + file + ")", + Advapi32.INSTANCE.GetNamedSecurityInfo( + file.getAbsolutePath(), + AccCtrl.SE_OBJECT_TYPE.SE_FILE_OBJECT, + infoType, + null, + null, + null, + null, + ppSecurityDescriptor), 0); + + assertTrue("IsValidSecurityDescriptor(" + file + ")", + Advapi32.INSTANCE.IsValidSecurityDescriptor(ppSecurityDescriptor.getValue())); + } finally { + file.delete(); + } + } finally { + Kernel32Util.freeLocalMemory(ppSecurityDescriptor.getValue()); + } + } - assertTrue(Advapi32.INSTANCE.IsValidSecurityDescriptor(ppSecurityDescriptor.getValue())); - Kernel32.INSTANCE.LocalFree(ppSecurityDescriptor.getValue()); - file.delete(); + public void testMakeSelfRelativeSD() { + SECURITY_DESCRIPTOR absolute = new SECURITY_DESCRIPTOR(64 * 1024); + assertTrue(Advapi32.INSTANCE.InitializeSecurityDescriptor(absolute, WinNT.SECURITY_DESCRIPTOR_REVISION)); + SECURITY_DESCRIPTOR_RELATIVE relative = new SECURITY_DESCRIPTOR_RELATIVE(64 * 1024); + IntByReference lpdwBufferLength = new IntByReference(64 * 1024); + assertTrue(Advapi32.INSTANCE.MakeSelfRelativeSD(absolute, relative, lpdwBufferLength)); + assertEquals(WinNT.SECURITY_DESCRIPTOR_REVISION, relative.Revision); + } + + public void testMakeAbsoluteSD() throws Exception { + SECURITY_DESCRIPTOR absolute = new SECURITY_DESCRIPTOR(64 * 1024); + + // Get a SD in self relative form + int infoType = OWNER_SECURITY_INFORMATION + | GROUP_SECURITY_INFORMATION + | DACL_SECURITY_INFORMATION; + + PointerByReference relativeByReference = new PointerByReference(); + File file = createTempFile(); + try { + try { + assertEquals("GetNamedSecurityInfo(" + file + ")", + Advapi32.INSTANCE.GetNamedSecurityInfo( + file.getAbsolutePath(), + AccCtrl.SE_OBJECT_TYPE.SE_FILE_OBJECT, + infoType, + null, + null, + null, + null, + relativeByReference), 0); + + SECURITY_DESCRIPTOR_RELATIVE relative = new SECURITY_DESCRIPTOR_RELATIVE(relativeByReference.getValue()); + + PSID pOwner = new PSID(WinNT.SECURITY_MAX_SID_SIZE); + PSID pGroup = new PSID(WinNT.SECURITY_MAX_SID_SIZE); + ACL pDacl = new ACL(ACL.MAX_ACL_SIZE); + ACL pSacl = new ACL(ACL.MAX_ACL_SIZE); + + IntByReference lpdwBufferLength = new IntByReference(absolute.size()); + IntByReference lpdwDaclSize = new IntByReference(ACL.MAX_ACL_SIZE); + IntByReference lpdwSaclSize= new IntByReference(ACL.MAX_ACL_SIZE); + IntByReference lpdwOwnerSize= new IntByReference(WinNT.SECURITY_MAX_SID_SIZE); + IntByReference lpdwPrimaryGroupSize = new IntByReference(WinNT.SECURITY_MAX_SID_SIZE); + + assertTrue(Advapi32.INSTANCE.MakeAbsoluteSD(relative, absolute, lpdwBufferLength, pDacl, lpdwDaclSize, pSacl, lpdwSaclSize, pOwner, lpdwOwnerSize, pGroup, lpdwPrimaryGroupSize)); + } finally { + file.delete(); + } + } finally { + Kernel32Util.freeLocalMemory(relativeByReference.getValue()); + } } public void testMapGenericReadMask() { @@ -1275,7 +1870,7 @@ public void testEncryptFile() throws Exception { // create a temp file File file = createTempFile(); - WString lpFileName = new WString(file.getAbsolutePath()); + String lpFileName = file.getAbsolutePath(); // encrypt a read only file file.setWritable(false); @@ -1292,7 +1887,7 @@ public void testDecryptFile() throws Exception { // create an encrypted file File file = createTempFile(); - WString lpFileName = new WString(file.getAbsolutePath()); + String lpFileName = file.getAbsolutePath(); assertTrue(Advapi32.INSTANCE.EncryptFile(lpFileName)); // decrypt a read only file @@ -1312,7 +1907,7 @@ // create a temp file File file = createTempFile(); - WString lpFileName = new WString(file.getAbsolutePath()); + String lpFileName = file.getAbsolutePath(); // unencrypted file assertTrue(Advapi32.INSTANCE.FileEncryptionStatus(lpFileName, lpStatus)); @@ -1338,7 +1933,7 @@ // create a temp dir String filePath = System.getProperty("java.io.tmpdir") + File.separator + System.nanoTime(); - WString DirPath = new WString(filePath); + String DirPath = filePath; File dir = new File(filePath); dir.mkdir(); @@ -1366,7 +1961,7 @@ public void testOpenEncryptedFileRaw() throws Exception { // create an encrypted file File file = createTempFile(); - WString lpFileName = new WString(file.getAbsolutePath()); + String lpFileName = file.getAbsolutePath(); assertTrue(Advapi32.INSTANCE.EncryptFile(lpFileName)); // open file for export @@ -1382,8 +1977,8 @@ public void testReadEncryptedFileRaw() throws Exception { // create an encrypted file File file = createTempFile(); - WString lpFileName = new WString(file.getAbsolutePath()); - assertTrue(Advapi32.INSTANCE.EncryptFile(lpFileName)); + String lpFileName = file.getAbsolutePath(); + assertTrue("EncryptFile(" + lpFileName + ")", Advapi32.INSTANCE.EncryptFile(lpFileName)); // open file for export ULONG ulFlags = new ULONG(0); @@ -1395,9 +1990,12 @@ final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); FE_EXPORT_FUNC pfExportCallback = new FE_EXPORT_FUNC() { @Override - public DWORD callback(ByteByReference pbData, Pointer + public DWORD callback(Pointer pbData, Pointer pvCallbackContext, ULONG ulLength) { - byte[] arr = pbData.getPointer().getByteArray(0, ulLength.intValue()); + if (pbData == null) { + throw new NullPointerException("Callback data unexpectedly missing"); + } + byte[] arr = pbData.getByteArray(0, ulLength.intValue()); try { outputStream.write(arr); } catch (IOException e) { @@ -1418,7 +2016,7 @@ public void testWriteEncryptedFileRaw() throws Exception { // create an encrypted file File file = createTempFile(); - WString lpFileName = new WString(file.getAbsolutePath()); + String lpFileName = file.getAbsolutePath(); assertTrue(Advapi32.INSTANCE.EncryptFile(lpFileName)); // open file for export @@ -1431,9 +2029,12 @@ final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); FE_EXPORT_FUNC pfExportCallback = new FE_EXPORT_FUNC() { @Override - public DWORD callback(ByteByReference pbData, Pointer + public DWORD callback(Pointer pbData, Pointer pvCallbackContext, ULONG ulLength) { - byte[] arr = pbData.getPointer().getByteArray(0, ulLength.intValue()); + if (pbData == null) { + throw new NullPointerException("Callback data unexpectedly null"); + } + byte[] arr = pbData.getByteArray(0, ulLength.intValue()); try { outputStream.write(arr); } catch (IOException e) { @@ -1449,8 +2050,8 @@ Advapi32.INSTANCE.CloseEncryptedFileRaw(pvContext.getValue()); // open file for import - WString lbFileName2 = new WString(System.getProperty("java.io.tmpdir") + - File.separator + "backup-" + file.getName()); + String lbFileName2 = System.getProperty("java.io.tmpdir") + + File.separator + "backup-" + file.getName(); ULONG ulFlags2 = new ULONG(CREATE_FOR_IMPORT); PointerByReference pvContext2 = new PointerByReference(); assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.OpenEncryptedFileRaw( @@ -1460,13 +2061,12 @@ final IntByReference elementsReadWrapper = new IntByReference(0); FE_IMPORT_FUNC pfImportCallback = new FE_IMPORT_FUNC() { @Override - public DWORD callback(ByteByReference pbData, Pointer pvCallbackContext, + public DWORD callback(Pointer pbData, Pointer pvCallbackContext, ULONGByReference ulLength) { int elementsRead = elementsReadWrapper.getValue(); int remainingElements = outputStream.size() - elementsRead; int length = Math.min(remainingElements, ulLength.getValue().intValue()); - pbData.getPointer().write(0, outputStream.toByteArray(), elementsRead, - length); + pbData.write(0, outputStream.toByteArray(), elementsRead, length); elementsReadWrapper.setValue(elementsRead + length); ulLength.setValue(new ULONG(length)); return new DWORD(W32Errors.ERROR_SUCCESS); @@ -1493,4 +2093,23 @@ fileWriter.close(); return file; } + + public void testCreateProcessWithLogonW() { + String winDir = Kernel32Util.getEnvironmentVariable("WINDIR"); + assertNotNull("No WINDIR value returned", winDir); + assertTrue("Specified WINDIR does not exist: " + winDir, new File(winDir).exists()); + + STARTUPINFO si = new STARTUPINFO(); + si.lpDesktop = null; + PROCESS_INFORMATION results = new PROCESS_INFORMATION(); + + // i have the same combination on my luggage + boolean result = Advapi32.INSTANCE.CreateProcessWithLogonW("A" + System.currentTimeMillis(), "localhost", "12345", Advapi32.LOGON_WITH_PROFILE, new File(winDir, "notepad.exe").getAbsolutePath(), "", 0, null, "", si, results); + + // we tried to run notepad as a bogus user, so it should fail. + assertFalse("CreateProcessWithLogonW should have returned false because the username was bogus.", result); + + // 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 -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/Advapi32UtilTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/Advapi32UtilTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/Advapi32UtilTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/Advapi32UtilTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,29 +1,32 @@ /* Copyright (c) 2010 Daniel Doubrovkine, All Rights Reserved - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * Lesser General Public License for more details. */ package com.sun.jna.platform.win32; +import static com.sun.jna.platform.win32.WinBase.FILE_DIR_DISALOWED; +import static com.sun.jna.platform.win32.WinBase.FILE_ENCRYPTABLE; +import static com.sun.jna.platform.win32.WinBase.FILE_IS_ENCRYPTED; + import java.io.File; import java.io.FileWriter; import java.util.Map; import java.util.TreeMap; -import junit.framework.TestCase; - -import com.sun.jna.WString; import com.sun.jna.platform.win32.Advapi32Util.Account; import com.sun.jna.platform.win32.Advapi32Util.EventLogIterator; import com.sun.jna.platform.win32.Advapi32Util.EventLogRecord; +import com.sun.jna.platform.win32.Advapi32Util.Privilege; import com.sun.jna.platform.win32.LMAccess.USER_INFO_1; +import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.platform.win32.WinNT.HANDLEByReference; import com.sun.jna.platform.win32.WinNT.PSID; import com.sun.jna.platform.win32.WinNT.SECURITY_DESCRIPTOR_RELATIVE; @@ -32,7 +35,7 @@ import com.sun.jna.platform.win32.WinReg.HKEY; import com.sun.jna.platform.win32.WinReg.HKEYByReference; -import static com.sun.jna.platform.win32.WinBase.*; +import junit.framework.TestCase; /** * @author dblock[at]dblock[dot]org @@ -43,17 +46,17 @@ junit.textui.TestRunner.run(Advapi32UtilTest.class); String currentUserName = Advapi32Util.getUserName(); System.out.println("GetUserName: " + currentUserName); - + for(Account group : Advapi32Util.getCurrentUserGroups()) { System.out.println(" " + group.fqn + " [" + group.sidString + "]"); } - + Account accountByName = Advapi32Util.getAccountByName(currentUserName); System.out.println("AccountByName: " + currentUserName); System.out.println(" Fqn: " + accountByName.fqn); System.out.println(" Domain: " + accountByName.domain); System.out.println(" Sid: " + accountByName.sidString); - + Account accountBySid = Advapi32Util.getAccountBySid(new PSID(accountByName.sid)); System.out.println("AccountBySid: " + accountByName.sidString); System.out.println(" Fqn: " + accountBySid.fqn); @@ -76,13 +79,13 @@ final boolean access = Advapi32Util.accessCheck(new File(System.getProperty("java.io.tmpdir")), Advapi32Util.AccessCheckPermission.EXECUTE); assertTrue(access); } - + public void testGetUsername() { String username = Advapi32Util.getUserName(); assertTrue(username.length() > 0); } - - public void testGetAccountBySid() { + + public void testGetAccountBySid() { String accountName = Advapi32Util.getUserName(); Account currentUser = Advapi32Util.getAccountByName(accountName); Account account = Advapi32Util.getAccountBySid(new PSID(currentUser.sid)); @@ -90,23 +93,43 @@ assertEquals(currentUser.fqn.toLowerCase(), account.fqn.toLowerCase()); assertEquals(currentUser.name.toLowerCase(), account.name.toLowerCase()); assertEquals(currentUser.domain.toLowerCase(), account.domain.toLowerCase()); - assertEquals(currentUser.sidString, account.sidString); + assertEquals(currentUser.sidString, account.sidString); } - public void testGetAccountByName() { + public void testGetAccountByName() { String accountName = Advapi32Util.getUserName(); Account account = Advapi32Util.getAccountByName(accountName); assertEquals(SID_NAME_USE.SidTypeUser, account.accountType); } - + public void testGetAccountNameFromSid() { - assertEquals("Everyone", Advapi32Util.getAccountBySid("S-1-1-0").name); + if(AbstractWin32TestSupport.isEnglishLocale) { + assertEquals("Everyone", Advapi32Util.getAccountBySid("S-1-1-0").name); + } else { + System.err.println("testGetAccountNameFromSid Test can only be run on english locale"); + } } public void testGetAccountSidFromName() { - assertEquals("S-1-1-0", Advapi32Util.getAccountByName("Everyone").sidString); + if(AbstractWin32TestSupport.isEnglishLocale) { + assertEquals("S-1-1-0", Advapi32Util.getAccountByName("Everyone").sidString); + } else { + System.err.println("testGetAccountSidFromName Test can only be run on english locale"); + } } - + + public void testGetAccountNameRoundtrip() { + // This test ensures getAccountBySid and getAccountByName are at least + // symmetrical. The names of the accounts are locale dependend so this is + // a compromise. (german: "Jeder", english: "Everybody") + String worldSID = "S-1-1-0"; // https://msdn.microsoft.com/en-us/library/windows/desktop/aa379649(v=vs.85).aspx + String accountNameResolved = Advapi32Util.getAccountBySid(worldSID).name; + String roundTripSid = Advapi32Util.getAccountByName(accountNameResolved).sidString; + assertNotNull(accountNameResolved); + assertTrue(! accountNameResolved.isEmpty()); + assertEquals(worldSID, roundTripSid); + } + public void testConvertSid() { String sidString = "S-1-1-0"; // Everyone byte[] sidBytes = Advapi32Util.convertStringSidToSid(sidString); @@ -114,7 +137,7 @@ String convertedSidString = Advapi32Util.convertSidToStringSid(new PSID(sidBytes)); assertEquals(convertedSidString, sidString); } - + public void testGetCurrentUserGroups() { Account[] groups = Advapi32Util.getCurrentUserGroups(); assertTrue(groups.length > 0); @@ -124,11 +147,11 @@ assertTrue(group.sid.length > 0); } } - + public void testGetUserGroups() { USER_INFO_1 userInfo = new USER_INFO_1(); - userInfo.usri1_name = new WString("JNANetapi32TestUser"); - userInfo.usri1_password = new WString("!JNAP$$Wrd0"); + userInfo.usri1_name = "JNANetapi32TestUser"; + userInfo.usri1_password = "!JNAP$$Wrd0"; userInfo.usri1_priv = LMAccess.USER_PRIV_USER; // ignore test if not able to add user (need to be administrator to do this). if (LMErr.NERR_Success != Netapi32.INSTANCE.NetUserAdd(null, 1, userInfo, null)) { @@ -138,7 +161,7 @@ HANDLEByReference phUser = new HANDLEByReference(); try { assertTrue(Advapi32.INSTANCE.LogonUser(userInfo.usri1_name.toString(), - null, userInfo.usri1_password.toString(), WinBase.LOGON32_LOGON_NETWORK, + null, userInfo.usri1_password.toString(), WinBase.LOGON32_LOGON_NETWORK, WinBase.LOGON32_PROVIDER_DEFAULT, phUser)); Account[] groups = Advapi32Util.getTokenGroups(phUser.getValue()); assertTrue(groups.length > 0); @@ -148,21 +171,22 @@ assertTrue(group.sid.length > 0); } } finally { - if (phUser.getValue() != WinBase.INVALID_HANDLE_VALUE) { - Kernel32.INSTANCE.CloseHandle(phUser.getValue()); - } + HANDLE hUser = phUser.getValue(); + if (!WinBase.INVALID_HANDLE_VALUE.equals(hUser)) { + Kernel32Util.closeHandle(hUser); + } } } finally { assertEquals("Error in NetUserDel", LMErr.NERR_Success, - Netapi32.INSTANCE.NetUserDel(null, userInfo.usri1_name.toString())); + Netapi32.INSTANCE.NetUserDel(null, userInfo.usri1_name.toString())); } } - + public void testGetUserAccount() { USER_INFO_1 userInfo = new USER_INFO_1(); - userInfo.usri1_name = new WString("JNANetapi32TestUser"); - userInfo.usri1_password = new WString("!JNAP$$Wrd0"); + userInfo.usri1_name = "JNANetapi32TestUser"; + userInfo.usri1_password = "!JNAP$$Wrd0"; userInfo.usri1_priv = LMAccess.USER_PRIV_USER; // ignore test if not able to add user (need to be administrator to do this). if (LMErr.NERR_Success != Netapi32.INSTANCE.NetUserAdd(null, 1, userInfo, null)) { @@ -172,47 +196,47 @@ HANDLEByReference phUser = new HANDLEByReference(); try { assertTrue(Advapi32.INSTANCE.LogonUser(userInfo.usri1_name.toString(), - null, userInfo.usri1_password.toString(), WinBase.LOGON32_LOGON_NETWORK, + null, userInfo.usri1_password.toString(), WinBase.LOGON32_LOGON_NETWORK, WinBase.LOGON32_PROVIDER_DEFAULT, phUser)); Advapi32Util.Account account = Advapi32Util.getTokenAccount(phUser.getValue()); assertTrue(account.name.length() > 0); assertEquals(userInfo.usri1_name.toString(), account.name); } finally { - if (phUser.getValue() != WinBase.INVALID_HANDLE_VALUE) { - Kernel32.INSTANCE.CloseHandle(phUser.getValue()); + HANDLE hUser = phUser.getValue(); + if (!WinBase.INVALID_HANDLE_VALUE.equals(hUser)) { + Kernel32Util.closeHandle(hUser); } } } finally { - assertEquals(LMErr.NERR_Success, Netapi32.INSTANCE.NetUserDel( - null, userInfo.usri1_name.toString())); + assertEquals(LMErr.NERR_Success, Netapi32.INSTANCE.NetUserDel(null, userInfo.usri1_name.toString())); } - } - + } + public void testRegistryKeyExists() { - assertTrue(Advapi32Util.registryKeyExists(WinReg.HKEY_LOCAL_MACHINE, + assertTrue(Advapi32Util.registryKeyExists(WinReg.HKEY_LOCAL_MACHINE, "")); - assertTrue(Advapi32Util.registryKeyExists(WinReg.HKEY_LOCAL_MACHINE, + assertTrue(Advapi32Util.registryKeyExists(WinReg.HKEY_LOCAL_MACHINE, "Software\\Microsoft")); - assertFalse(Advapi32Util.registryKeyExists(WinReg.HKEY_LOCAL_MACHINE, + assertFalse(Advapi32Util.registryKeyExists(WinReg.HKEY_LOCAL_MACHINE, "KeyDoesNotExist\\SubKeyDoesNotExist")); } - + public void testRegistryValueExists() { - assertFalse(Advapi32Util.registryValueExists(WinReg.HKEY_LOCAL_MACHINE, + assertFalse(Advapi32Util.registryValueExists(WinReg.HKEY_LOCAL_MACHINE, "Software\\Microsoft", "")); - assertFalse(Advapi32Util.registryValueExists(WinReg.HKEY_LOCAL_MACHINE, + assertFalse(Advapi32Util.registryValueExists(WinReg.HKEY_LOCAL_MACHINE, "Software\\Microsoft", "KeyDoesNotExist")); - assertTrue(Advapi32Util.registryValueExists(WinReg.HKEY_LOCAL_MACHINE, + assertTrue(Advapi32Util.registryValueExists(WinReg.HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control", "SystemBootDevice")); - } - + } + public void testRegistryCreateDeleteKey() { Advapi32Util.registryCreateKey(WinReg.HKEY_CURRENT_USER, "Software", "JNA"); assertTrue(Advapi32Util.registryKeyExists(WinReg.HKEY_CURRENT_USER, "Software\\JNA")); Advapi32Util.registryDeleteKey(WinReg.HKEY_CURRENT_USER, "Software", "JNA"); assertFalse(Advapi32Util.registryKeyExists(WinReg.HKEY_CURRENT_USER, "Software\\JNA")); } - + public void testRegistryCreateKeyDisposition() { Advapi32Util.registryCreateKey(WinReg.HKEY_CURRENT_USER, "Software", "JNA"); Advapi32Util.registryDeleteKey(WinReg.HKEY_CURRENT_USER, "Software", "JNA"); @@ -226,47 +250,47 @@ Advapi32Util.registryCreateKey(WinReg.HKEY_CURRENT_USER, "Software", "JNA"); Advapi32Util.registrySetIntValue(WinReg.HKEY_CURRENT_USER, "Software\\JNA", "IntValue", 42); assertTrue(Advapi32Util.registryValueExists(WinReg.HKEY_CURRENT_USER, "Software\\JNA", "IntValue")); - Advapi32Util.registryDeleteValue(WinReg.HKEY_CURRENT_USER, "Software\\JNA", "IntValue"); + Advapi32Util.registryDeleteValue(WinReg.HKEY_CURRENT_USER, "Software\\JNA", "IntValue"); assertFalse(Advapi32Util.registryValueExists(WinReg.HKEY_CURRENT_USER, "Software\\JNA", "IntValue")); Advapi32Util.registryDeleteKey(WinReg.HKEY_CURRENT_USER, "Software", "JNA"); } - + public void testRegistrySetGetIntValue() { Advapi32Util.registryCreateKey(WinReg.HKEY_CURRENT_USER, "Software", "JNA"); Advapi32Util.registrySetIntValue(WinReg.HKEY_CURRENT_USER, "Software\\JNA", "IntValue", 42); - assertEquals(42, Advapi32Util.registryGetIntValue(WinReg.HKEY_CURRENT_USER, + assertEquals(42, Advapi32Util.registryGetIntValue(WinReg.HKEY_CURRENT_USER, "Software\\JNA", "IntValue")); assertTrue(Advapi32Util.registryValueExists(WinReg.HKEY_CURRENT_USER, "Software\\JNA", "IntValue")); Advapi32Util.registryDeleteKey(WinReg.HKEY_CURRENT_USER, "Software", "JNA"); } - + public void testRegistrySetGetLongValue() { Advapi32Util.registryCreateKey(WinReg.HKEY_CURRENT_USER, "Software", "JNA"); Advapi32Util.registrySetLongValue(WinReg.HKEY_CURRENT_USER, "Software\\JNA", "LongValue", 1234L); - assertEquals(1234L, Advapi32Util.registryGetLongValue(WinReg.HKEY_CURRENT_USER, + assertEquals(1234L, Advapi32Util.registryGetLongValue(WinReg.HKEY_CURRENT_USER, "Software\\JNA", "LongValue")); assertTrue(Advapi32Util.registryValueExists(WinReg.HKEY_CURRENT_USER, "Software\\JNA", "LongValue")); Advapi32Util.registryDeleteKey(WinReg.HKEY_CURRENT_USER, "Software", "JNA"); } - + public void testRegistrySetGetStringValue() { Advapi32Util.registryCreateKey(WinReg.HKEY_CURRENT_USER, "Software", "JNA"); Advapi32Util.registrySetStringValue(WinReg.HKEY_CURRENT_USER, "Software\\JNA", "StringValue", "Hello World"); - assertEquals("Hello World", Advapi32Util.registryGetStringValue(WinReg.HKEY_CURRENT_USER, + assertEquals("Hello World", Advapi32Util.registryGetStringValue(WinReg.HKEY_CURRENT_USER, "Software\\JNA", "StringValue")); assertTrue(Advapi32Util.registryValueExists(WinReg.HKEY_CURRENT_USER, "Software\\JNA", "StringValue")); - Advapi32Util.registryDeleteKey(WinReg.HKEY_CURRENT_USER, "Software", "JNA"); + Advapi32Util.registryDeleteKey(WinReg.HKEY_CURRENT_USER, "Software", "JNA"); } public void testRegistrySetGetExpandableStringValue() { Advapi32Util.registryCreateKey(WinReg.HKEY_CURRENT_USER, "Software", "JNA"); Advapi32Util.registrySetExpandableStringValue(WinReg.HKEY_CURRENT_USER, "Software\\JNA", "StringValue", "Temp is %TEMP%"); - assertEquals("Temp is %TEMP%", Advapi32Util.registryGetExpandableStringValue(WinReg.HKEY_CURRENT_USER, + assertEquals("Temp is %TEMP%", Advapi32Util.registryGetExpandableStringValue(WinReg.HKEY_CURRENT_USER, "Software\\JNA", "StringValue")); assertTrue(Advapi32Util.registryValueExists(WinReg.HKEY_CURRENT_USER, "Software\\JNA", "StringValue")); - Advapi32Util.registryDeleteKey(WinReg.HKEY_CURRENT_USER, "Software", "JNA"); + Advapi32Util.registryDeleteKey(WinReg.HKEY_CURRENT_USER, "Software", "JNA"); } - + public void testRegistrySetGetStringArray() { Advapi32Util.registryCreateKey(WinReg.HKEY_CURRENT_USER, "Software", "JNA"); String[] dataWritten = { "Hello", "World" }; @@ -289,14 +313,14 @@ Advapi32Util.registryCreateKey(WinReg.HKEY_CURRENT_USER, "Software", "JNA"); Advapi32Util.registrySetBinaryValue(WinReg.HKEY_CURRENT_USER, "Software\\JNA", "BinaryValue", data); byte[] read = Advapi32Util.registryGetBinaryValue(WinReg.HKEY_CURRENT_USER, "Software\\JNA", "BinaryValue"); - assertEquals(data.length, read.length); + assertEquals(data.length, read.length); for(int i = 0; i < data.length; i++) { assertEquals(data[i], read[i]); } assertTrue(Advapi32Util.registryValueExists(WinReg.HKEY_CURRENT_USER, "Software\\JNA", "BinaryValue")); Advapi32Util.registryDeleteKey(WinReg.HKEY_CURRENT_USER, "Software", "JNA"); } - + public void testRegistryGetKeys() { Advapi32Util.registryCreateKey(WinReg.HKEY_CURRENT_USER, "Software", "JNA"); Advapi32Util.registryCreateKey(WinReg.HKEY_CURRENT_USER, "Software\\JNA", "Key1"); @@ -307,9 +331,9 @@ assertEquals(subKeys[1], "Key2"); Advapi32Util.registryDeleteKey(WinReg.HKEY_CURRENT_USER, "Software\\JNA", "Key1"); Advapi32Util.registryDeleteKey(WinReg.HKEY_CURRENT_USER, "Software\\JNA", "Key2"); - Advapi32Util.registryDeleteKey(WinReg.HKEY_CURRENT_USER, "Software", "JNA"); + Advapi32Util.registryDeleteKey(WinReg.HKEY_CURRENT_USER, "Software", "JNA"); } - + public void testRegistryGetCloseKey() { Advapi32Util.registryCreateKey(WinReg.HKEY_CURRENT_USER, "Software", "JNA"); Advapi32Util.registryCreateKey(WinReg.HKEY_CURRENT_USER, "Software\\JNA", "Key1"); @@ -324,14 +348,14 @@ Advapi32Util.registryDeleteKey(WinReg.HKEY_CURRENT_USER, "Software\\JNA", "Key2"); Advapi32Util.registryDeleteKey(WinReg.HKEY_CURRENT_USER, "Software", "JNA"); } - + public void testRegistryGetValues() { String uu = new String("A" + "\\u00ea" + "\\u00f1" + "\\u00fc" + "C"); Advapi32Util.registryCreateKey(WinReg.HKEY_CURRENT_USER, "Software", "JNA"); Advapi32Util.registrySetIntValue(WinReg.HKEY_CURRENT_USER, "Software\\JNA", "FourtyTwo" + uu, 42); Advapi32Util.registrySetStringValue(WinReg.HKEY_CURRENT_USER, "Software\\JNA", "42" + uu, "FourtyTwo" + uu); Advapi32Util.registrySetExpandableStringValue(WinReg.HKEY_CURRENT_USER, "Software\\JNA", "ExpandableString", "%TEMP%"); - byte[] dataWritten = { 0xD, 0xE, 0xA, 0xD, 0xB, 0xE, 0xE, 0xF }; + byte[] dataWritten = { 0xD, 0xE, 0xA, 0xD, 0xB, 0xE, 0xE, 0xF }; Advapi32Util.registrySetBinaryValue(WinReg.HKEY_CURRENT_USER, "Software\\JNA", "DeadBeef", dataWritten); String[] stringsWritten = { "Hello", "World", "Hello World", uu }; Advapi32Util.registrySetStringArray(WinReg.HKEY_CURRENT_USER, "Software\\JNA", "StringArray", stringsWritten); @@ -355,7 +379,7 @@ } stringsRead = (String[]) values.get("EmptyStringArray"); assertEquals(0, stringsRead.length); - Advapi32Util.registryDeleteKey(WinReg.HKEY_CURRENT_USER, "Software", "JNA"); + Advapi32Util.registryDeleteKey(WinReg.HKEY_CURRENT_USER, "Software", "JNA"); } public void testRegistryGetEmptyValues() { @@ -397,16 +421,16 @@ } } } - - public void testIsWellKnownSid() { + + public void testIsWellKnownSid() { String everyoneString = "S-1-1-0"; - assertTrue(Advapi32Util.isWellKnownSid(everyoneString, WELL_KNOWN_SID_TYPE.WinWorldSid)); + assertTrue(Advapi32Util.isWellKnownSid(everyoneString, WELL_KNOWN_SID_TYPE.WinWorldSid)); assertFalse(Advapi32Util.isWellKnownSid(everyoneString, WELL_KNOWN_SID_TYPE.WinAccountAdministratorSid)); byte[] everyoneBytes = Advapi32Util.convertStringSidToSid(everyoneString); - assertTrue(Advapi32Util.isWellKnownSid(everyoneBytes, WELL_KNOWN_SID_TYPE.WinWorldSid)); + assertTrue(Advapi32Util.isWellKnownSid(everyoneBytes, WELL_KNOWN_SID_TYPE.WinWorldSid)); assertFalse(Advapi32Util.isWellKnownSid(everyoneBytes, WELL_KNOWN_SID_TYPE.WinAccountAdministratorSid)); } - + public void testEventLogIteratorForwards() { EventLogIterator iter = new EventLogIterator("Application"); try { @@ -419,18 +443,18 @@ assertNotNull(record.getType().name()); assertNotNull(record.getSource()); if (record.getRecord().DataLength.intValue() > 0) { - assertEquals(record.getData().length, + assertEquals(record.getData().length, record.getRecord().DataLength.intValue()); } else { assertNull(record.getData()); } if (record.getRecord().NumStrings.intValue() > 0) { - assertEquals(record.getStrings().length, + assertEquals(record.getStrings().length, record.getRecord().NumStrings.intValue()); } else { assertNull(record.getStrings()); } - + if (max-- <= 0) { break; // shorten test } @@ -445,9 +469,9 @@ iter.close(); } } - + public void testEventLogIteratorBackwards() { - EventLogIterator iter = new EventLogIterator(null, + EventLogIterator iter = new EventLogIterator(null, "Application", WinNT.EVENTLOG_BACKWARDS_READ); try { int max = 100; @@ -470,10 +494,10 @@ iter.close(); } } - + public void testGetEnvironmentBlock() { String expected = "KEY=value\0" - + "KEY_EMPTY=\0" + + "KEY_EMPTY=\0" + "KEY_NUMBER=2\0" + "\0"; @@ -482,28 +506,28 @@ mockEnvironment.put("KEY", "value"); mockEnvironment.put("KEY_EMPTY", ""); mockEnvironment.put("KEY_NUMBER", "2"); - mockEnvironment.put("KEY_NULL", null); + mockEnvironment.put("KEY_NULL", null); String block = Advapi32Util.getEnvironmentBlock(mockEnvironment); assertEquals("Environment block must comprise key=value pairs separated by NUL characters", expected, block); } - + public void testGetFileSecurityDescriptor() throws Exception { - File file = createTempFile(); + File file = createTempFile(); SECURITY_DESCRIPTOR_RELATIVE sdr = Advapi32Util.getFileSecurityDescriptor(file, false); assertTrue(Advapi32.INSTANCE.IsValidSecurityDescriptor(sdr.getPointer())); file.delete(); } - + public void testSetFileSecurityDescriptor() throws Exception { - File file = createTempFile(); - SECURITY_DESCRIPTOR_RELATIVE sdr = Advapi32Util.getFileSecurityDescriptor(file, false); + File file = createTempFile(); + SECURITY_DESCRIPTOR_RELATIVE sdr = Advapi32Util.getFileSecurityDescriptor(file, false); Advapi32Util.setFileSecurityDescriptor(file, sdr, false, true, true, false, true, false); sdr = Advapi32Util.getFileSecurityDescriptor(file, false); - assertTrue(Advapi32.INSTANCE.IsValidSecurityDescriptor(sdr.getPointer())); + assertTrue(Advapi32.INSTANCE.IsValidSecurityDescriptor(sdr.getPointer())); file.delete(); } - + public void testEncryptFile() throws Exception { File file = createTempFile(); assertEquals(FILE_ENCRYPTABLE, Advapi32Util.fileEncryptionStatus(file)); @@ -522,7 +546,7 @@ } public void testDisableEncryption() throws Exception { - File dir = new File(System.getProperty("java.io.tmpdir") + File.separator + File dir = new File(System.getProperty("java.io.tmpdir") + File.separator + System.nanoTime()); dir.mkdir(); assertEquals(FILE_ENCRYPTABLE, Advapi32Util.fileEncryptionStatus(dir)); @@ -535,29 +559,29 @@ } dir.delete(); } - + public void testBackupEncryptedFile() throws Exception { // backup an encrypted file File srcFile = createTempFile(); Advapi32Util.encryptFile(srcFile); - File dest = new File(System.getProperty("java.io.tmpdir") + File.separator + File dest = new File(System.getProperty("java.io.tmpdir") + File.separator + "backup" + System.nanoTime()); dest.mkdir(); Advapi32Util.backupEncryptedFile(srcFile, dest); // simple check to see if a backup file exist - File backupFile = new File(dest.getAbsolutePath() + File.separator + + File backupFile = new File(dest.getAbsolutePath() + File.separator + srcFile.getName()); assertTrue(backupFile.exists()); assertEquals(srcFile.length(), backupFile.length()); // backup an encrypted directory - File srcDir = new File(System.getProperty("java.io.tmpdir") + File.separator + File srcDir = new File(System.getProperty("java.io.tmpdir") + File.separator + System.nanoTime()); srcDir.mkdir(); Advapi32Util.encryptFile(srcDir); - + Advapi32Util.backupEncryptedFile(srcDir, dest); // Check to see if a backup directory exist @@ -576,8 +600,37 @@ dest.delete(); } + /** + * Test Privilege class + */ + public void testPrivilege() { + // Test multiple known privileges + Privilege privilege = new Privilege(WinNT.SE_ASSIGNPRIMARYTOKEN_NAME, WinNT.SE_BACKUP_NAME); + try { + privilege.enable(); + // Will throw if it fails p.enable() fails + } + finally { + privilege.close(); + } + + // Test unknown privilege + try { + privilege = new Privilege("NOT_A_PRIVILEGE"); + } + catch (IllegalArgumentException ex) { + // Exception is expected + } + catch (Exception ex) { + fail("Encountered unknown exception - " + ex.getMessage()); + } + finally { + privilege.close(); + } + } + private File createTempFile() throws Exception{ - String filePath = System.getProperty("java.io.tmpdir") + System.nanoTime() + String filePath = System.getProperty("java.io.tmpdir") + System.nanoTime() + ".text"; File file = new File(filePath); file.createNewFile(); diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/ComEventCallbacks_Test.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/ComEventCallbacks_Test.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/ComEventCallbacks_Test.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/ComEventCallbacks_Test.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,204 +1,361 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import com.sun.jna.Pointer; -import com.sun.jna.WString; -import com.sun.jna.platform.win32.Guid; -import com.sun.jna.platform.win32.Guid.CLSID; -import com.sun.jna.platform.win32.Guid.IID; -import com.sun.jna.platform.win32.Guid.REFIID; -import com.sun.jna.platform.win32.Kernel32; -import com.sun.jna.platform.win32.OaIdl.DISPID; -import com.sun.jna.platform.win32.OaIdl.DISPIDByReference; -import com.sun.jna.platform.win32.OaIdl.EXCEPINFO; -import com.sun.jna.platform.win32.Ole32; -import com.sun.jna.platform.win32.OleAuto.DISPPARAMS; -import com.sun.jna.platform.win32.User32; -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.DWORDByReference; -import com.sun.jna.platform.win32.WinDef.LCID; -import com.sun.jna.platform.win32.WinDef.UINT; -import com.sun.jna.platform.win32.WinDef.UINTByReference; -import com.sun.jna.platform.win32.WinDef.WORD; -import com.sun.jna.platform.win32.WinError; -import com.sun.jna.platform.win32.WinNT.HRESULT; -import com.sun.jna.platform.win32.WinUser; -import com.sun.jna.ptr.IntByReference; -import com.sun.jna.ptr.PointerByReference; - -public class ComEventCallbacks_Test { - - final String WORD_APPLICATION_INTERFACE = "{00020970-0000-0000-C000-000000000046}"; - final String APPLICATION_EVENTS_4 = "{00020A01-0000-0000-C000-000000000046}"; - - @Before - public void before() { - HRESULT hr = Ole32.INSTANCE.CoInitializeEx(null, Ole32.COINIT_MULTITHREADED); - COMUtils.checkRC(hr); - } - - @After - public void after() { - Ole32.INSTANCE.CoUninitialize(); - } - - class Application_Events4 implements IDispatchCallback { - public DispatchListener listener = new DispatchListener(this); - - @Override - public Pointer getPointer() { - return this.listener.getPointer(); - } - - //------------------------ IDispatch ------------------------------ - @Override - public HRESULT GetTypeInfoCount(UINTByReference pctinfo) { - return new HRESULT(WinError.E_NOTIMPL); - } - - @Override - public HRESULT GetTypeInfo(UINT iTInfo, LCID lcid, PointerByReference ppTInfo) { - return new HRESULT(WinError.E_NOTIMPL); - } - - @Override - public HRESULT GetIDsOfNames(REFIID.ByValue riid, WString[] rgszNames, int cNames, LCID lcid, DISPIDByReference rgDispId) { - return new HRESULT(WinError.E_NOTIMPL); - } - - public boolean Invoke_called = false; - @Override - public HRESULT Invoke(DISPID dispIdMember, REFIID.ByValue riid, LCID lcid, - WORD wFlags, DISPPARAMS.ByReference pDispParams, - VARIANT.ByReference pVarResult, EXCEPINFO.ByReference pExcepInfo, - IntByReference puArgErr) { - this.Invoke_called = true; - - return new HRESULT(WinError.E_NOTIMPL); - } - - - //------------------------ IUnknown ------------------------------ - public boolean QueryInterface_called = false; - @Override - public HRESULT QueryInterface(REFIID.ByValue refid, PointerByReference ppvObject) { - this.QueryInterface_called = true; - if (null==ppvObject) { - return new HRESULT(WinError.E_POINTER); - } - - String s = refid.toGuidString(); - IID appEvnts4 = new IID(APPLICATION_EVENTS_4); - REFIID.ByValue riid = new REFIID.ByValue(appEvnts4.getPointer()); - - if (refid.equals(riid)) { - ppvObject.setValue(this.getPointer()); - return WinError.S_OK; - } - - if (new Guid.IID(refid.getPointer()).equals(Unknown.IID_IUNKNOWN)) { - ppvObject.setValue(this.getPointer()); - return WinError.S_OK; - } - - if (new Guid.IID(refid.getPointer()).equals(Dispatch.IID_IDISPATCH)) { - ppvObject.setValue(this.getPointer()); - return WinError.S_OK; - } - - return new HRESULT(WinError.E_NOINTERFACE); - } - - public int AddRef() { - return 0; - } - - public int Release() { - return 0; - } - - } - - @Test - public void cause_Quit_Event() { - // Create word object - CLSID clsid = new CLSID("{000209FF-0000-0000-C000-000000000046}"); - PointerByReference ppWordApp = new PointerByReference(); - HRESULT hr = Ole32.INSTANCE - .CoCreateInstance(clsid, null, WTypes.CLSCTX_SERVER, IDispatch.IID_IDISPATCH, ppWordApp); -// HRESULT hr =OleAuto.INSTANCE.GetActiveObject(clsid, null, ppWordApp); - COMUtils.checkRC(hr); - - // query for ConnectionPointContainer - Unknown unk = new Unknown(ppWordApp.getValue()); - PointerByReference ppCpc = new PointerByReference(); - IID cpcIID = new IID("{B196B284-BAB4-101A-B69C-00AA00341D07}"); - hr = unk.QueryInterface(new REFIID.ByValue(cpcIID), ppCpc); - COMUtils.checkRC(hr); - ConnectionPointContainer cpc = new ConnectionPointContainer(ppCpc.getValue()); - - // find connection point for Application_Events4 - IID appEvnts4 = new IID(APPLICATION_EVENTS_4); - REFIID riid = new REFIID(appEvnts4.getPointer()); - PointerByReference ppCp = new PointerByReference(); - hr = cpc.FindConnectionPoint(riid, ppCp); - COMUtils.checkRC(hr); - final ConnectionPoint cp = new ConnectionPoint(ppCp.getValue()); - IID cp_iid = new IID(); - hr = cp.GetConnectionInterface(cp_iid); - COMUtils.checkRC(hr); - - final Application_Events4 listener = new Application_Events4(); - final DWORDByReference pdwCookie = new DWORDByReference(); - HRESULT hr1 = cp.Advise(listener, pdwCookie); - COMUtils.checkRC(hr1); - -// Assert.assertTrue(listener.QueryInterface_called); -// - // Call Quit - Dispatch d = new Dispatch(ppWordApp.getValue()); - DISPID dispIdMember = new DISPID(1105); // Quit - REFIID.ByValue niid = new REFIID.ByValue(Guid.IID_NULL); - LCID lcid = Kernel32.INSTANCE.GetSystemDefaultLCID(); - WinDef.WORD wFlags = new WinDef.WORD(1); - DISPPARAMS.ByReference pDispParams = new DISPPARAMS.ByReference(); - VARIANT.ByReference pVarResult = new VARIANT.ByReference(); - IntByReference puArgErr = new IntByReference(); - EXCEPINFO.ByReference pExcepInfo = new EXCEPINFO.ByReference(); - hr = d.Invoke(dispIdMember, niid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); - COMUtils.checkRC(hr); - - //Wait for event to happen - try { - Thread.sleep(200); -// WinUser.MSG msg = new WinUser.MSG(); -// while (((User32.INSTANCE.GetMessage(msg, null, 0, 0)) != 0)) { -// User32.INSTANCE.TranslateMessage(msg); -// User32.INSTANCE.DispatchMessage(msg); -// } - } catch (Exception e) { - e.printStackTrace(); - } - - Assert.assertTrue(listener.Invoke_called); - } - -} +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ +package com.sun.jna.platform.win32.COM; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.sun.jna.Pointer; +import com.sun.jna.WString; +import com.sun.jna.platform.win32.AbstractWin32TestSupport; +import com.sun.jna.platform.win32.Guid; +import com.sun.jna.platform.win32.Guid.CLSID; +import com.sun.jna.platform.win32.Guid.IID; +import com.sun.jna.platform.win32.Guid.REFIID; +import com.sun.jna.platform.win32.OaIdl; +import com.sun.jna.platform.win32.OaIdl.DISPID; +import com.sun.jna.platform.win32.OaIdl.DISPIDByReference; +import com.sun.jna.platform.win32.OaIdl.EXCEPINFO; +import com.sun.jna.platform.win32.OaIdl.VARIANT_BOOLByReference; +import com.sun.jna.platform.win32.Ole32; +import com.sun.jna.platform.win32.OleAuto; +import com.sun.jna.platform.win32.OleAuto.DISPPARAMS; +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; +import com.sun.jna.platform.win32.WinDef.DWORDByReference; +import com.sun.jna.platform.win32.WinDef.LCID; +import com.sun.jna.platform.win32.WinDef.UINT; +import com.sun.jna.platform.win32.WinDef.UINTByReference; +import com.sun.jna.platform.win32.WinDef.WORD; +import com.sun.jna.platform.win32.WinError; +import com.sun.jna.platform.win32.WinNT.HRESULT; +import com.sun.jna.ptr.IntByReference; +import com.sun.jna.ptr.PointerByReference; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.junit.Assert; + +public class ComEventCallbacks_Test { + static { + ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true); + } + + private final CLSID CLSID_InternetExplorer = new CLSID("{0002DF01-0000-0000-C000-000000000046}"); + private final IID IID_IConnectionPointContainer = new IID("{B196B284-BAB4-101A-B69C-00AA00341D07}"); + private final IID IID_DWebBrowserEvents2 = new IID("{34A715A0-6587-11D0-924A-0020AFC7AC4D}"); + private final REFIID niid = new REFIID(Guid.IID_NULL); + private final LCID lcid = new LCID(0x0409); // LCID for english locale + private final WinDef.WORD methodFlags = new WinDef.WORD(OleAuto.DISPATCH_METHOD); + private final WinDef.WORD propertyPutFlags = new WinDef.WORD(OleAuto.DISPATCH_PROPERTYPUT); + + private final DISPIDByReference dispIdVisible = new DISPIDByReference(); + private final DISPIDByReference dispIdQuit = new DISPIDByReference(); + private final DISPIDByReference dispIdNavigate = new DISPIDByReference(); + + private PointerByReference ieApp; + private Dispatch ieDispatch; + + + + @Before + public void before() { + AbstractWin32TestSupport.killProcessByName("iexplore.exe"); + try { + Thread.sleep(5 * 1000); + } catch (InterruptedException ex) {} + + HRESULT hr = Ole32.INSTANCE.CoInitializeEx(null, Ole32.COINIT_MULTITHREADED); + COMUtils.checkRC(hr); + + // Create InternetExplorer object + 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()); + ieDispatch.AddRef(); + hr = ieDispatch.GetIDsOfNames(new REFIID(Guid.IID_NULL), new WString[]{new WString("Quit")}, 1, lcid, dispIdQuit); + COMUtils.checkRC(hr); + hr = ieDispatch.GetIDsOfNames(new REFIID(Guid.IID_NULL), new WString[]{new WString("Visible")}, 1, lcid, dispIdVisible); + COMUtils.checkRC(hr); + hr = ieDispatch.GetIDsOfNames(new REFIID(Guid.IID_NULL), new WString[]{new WString("Navigate")}, 1, lcid, dispIdNavigate); + COMUtils.checkRC(hr); + } + + @After + public void after() { + // Shutdown Internet Explorer + DISPPARAMS.ByReference pDispParams = new DISPPARAMS.ByReference(); + VARIANT.ByReference pVarResult = new VARIANT.ByReference(); + IntByReference puArgErr = new IntByReference(); + EXCEPINFO.ByReference pExcepInfo = new EXCEPINFO.ByReference(); + + HRESULT hr = ieDispatch.Invoke(dispIdQuit.getValue(), niid, lcid, methodFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + COMUtils.checkRC(hr, pExcepInfo, puArgErr); + + ieDispatch.Release(); + Ole32.INSTANCE.CoUninitialize(); + } + + @Test + public void queryInterface_ConnectionPointContainer() { + Unknown unk = new Unknown(ieApp.getValue()); + PointerByReference ppCpc = new PointerByReference(); + HRESULT hr = unk.QueryInterface(new REFIID(IID_IConnectionPointContainer), ppCpc); + COMUtils.checkRC(hr); + // On success the returned pointer must not be null + Assert.assertNotNull(ppCpc.getPointer()); + } + + @Test + public void FindConnectionPoint() { + // query for ConnectionPointContainer + Unknown unk = new Unknown(ieApp.getValue()); + PointerByReference ppCpc = new PointerByReference(); + HRESULT hr = unk.QueryInterface(new REFIID(IID_IConnectionPointContainer), ppCpc); + COMUtils.checkRC(hr); + ConnectionPointContainer cpc = new ConnectionPointContainer(ppCpc.getValue()); + + // find connection point for DWebBrowserEvents2 + REFIID riid = new REFIID(IID_DWebBrowserEvents2); + PointerByReference ppCp = new PointerByReference(); + hr = cpc.FindConnectionPoint(riid, ppCp); + COMUtils.checkRC(hr); + + // On success the returned pointer must not be null + Assert.assertNotNull(ppCpc.getPointer()); + } + + @Test + public void GetConnectionInterface() { + // query for ConnectionPointContainer + Unknown unk = new Unknown(this.ieApp.getValue()); + PointerByReference ppCpc = new PointerByReference(); + HRESULT hr = unk.QueryInterface(new REFIID(IID_IConnectionPointContainer), ppCpc); + COMUtils.checkRC(hr); + ConnectionPointContainer cpc = new ConnectionPointContainer(ppCpc.getValue()); + + // find connection point for DWebBrowserEvents2 + REFIID riid = new REFIID(IID_DWebBrowserEvents2); + PointerByReference ppCp = new PointerByReference(); + hr = cpc.FindConnectionPoint(riid, ppCp); + COMUtils.checkRC(hr); + ConnectionPoint cp = new ConnectionPoint(ppCp.getValue()); + + IID cp_iid = new IID(); + hr = cp.GetConnectionInterface(cp_iid); + COMUtils.checkRC(hr); + + Assert.assertEquals(IID_DWebBrowserEvents2, cp_iid); + } + + class DWebBrowserEvents2_Listener implements IDispatchCallback { + + private final int DISPID_NavigateComplete2 = 0x000000fc; + private final int DISPID_BeforeNavigate2 = 0x000000fa; + + public DispatchListener listener = new DispatchListener(this); + + @Override + public Pointer getPointer() { + return this.listener.getPointer(); + } + + //------------------------ IDispatch ------------------------------ + @Override + public HRESULT GetTypeInfoCount(UINTByReference pctinfo) { + return new HRESULT(WinError.E_NOTIMPL); + } + + @Override + public HRESULT GetTypeInfo(UINT iTInfo, LCID lcid, PointerByReference ppTInfo) { + return new HRESULT(WinError.E_NOTIMPL); + } + + @Override + public HRESULT GetIDsOfNames(REFIID riid, WString[] rgszNames, int cNames, LCID lcid, DISPIDByReference rgDispId) { + return new HRESULT(WinError.E_NOTIMPL); + } + + public volatile boolean blockNavigation = false; + public volatile boolean navigateComplete2Called = false; + public volatile String navigateComplete2String = null; + + @Override + public HRESULT Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, + WORD wFlags, DISPPARAMS.ByReference pDispParams, + VARIANT.ByReference pVarResult, EXCEPINFO.ByReference pExcepInfo, + IntByReference puArgErr) { + + VARIANT[] arguments = pDispParams.getArgs(); + + try { + switch (dispIdMember.intValue()) { + case DISPID_NavigateComplete2: + navigateComplete2Called = true; + // URL ist passed as VARIANT$ByReference + VARIANT urlByRef = arguments[0]; + navigateComplete2String = ((VARIANT) urlByRef.getValue()).stringValue(); + break; + case DISPID_BeforeNavigate2: + VARIANT Cancel = arguments[0]; + VARIANT Headers = arguments[1]; + VARIANT PostData = arguments[2]; + VARIANT TargetFrameName = arguments[3]; + VARIANT Flags = arguments[4]; + VARIANT URL = arguments[5]; + VARIANT pDisp = arguments[6]; + VARIANT_BOOLByReference cancelValue = ((VARIANT_BOOLByReference) Cancel.getValue()); + if (blockNavigation) { + cancelValue.setValue(Variant.VARIANT_TRUE); + } + break; + } + } catch (Throwable ex) { + ex.printStackTrace(System.out); + System.out.println(ex); + } + + return new HRESULT(WinError.E_NOTIMPL); + } + + //------------------------ IUnknown ------------------------------ + public volatile boolean QueryInterface_called = false; + + @Override + public HRESULT QueryInterface(REFIID refiid, PointerByReference ppvObject) { + this.QueryInterface_called = true; + if (null == ppvObject) { + return new HRESULT(WinError.E_POINTER); + } + + if (refiid.getValue().equals(IID_DWebBrowserEvents2)) { + ppvObject.setValue(this.getPointer()); + return WinError.S_OK; + } + + if (refiid.getValue().equals(Unknown.IID_IUNKNOWN)) { + ppvObject.setValue(this.getPointer()); + return WinError.S_OK; + } + + if (refiid.getValue().equals(Dispatch.IID_IDISPATCH)) { + ppvObject.setValue(this.getPointer()); + return WinError.S_OK; + } + + ppvObject.setValue(Pointer.NULL); + return new HRESULT(WinError.E_NOINTERFACE); + } + + public int AddRef() { + return 0; + } + + public int Release() { + return 0; + } + + } + + @Test + public void testComEventCallback() throws InterruptedException { + VARIANT.ByReference pVarResult = new VARIANT.ByReference(); + IntByReference puArgErr = new IntByReference(); + EXCEPINFO.ByReference pExcepInfo = new EXCEPINFO.ByReference(); + HRESULT hr; + + DISPPARAMS.ByReference pDispParams; + + pDispParams = new DISPPARAMS.ByReference(); + pDispParams.setArgs(new VARIANT[] {new VARIANT(true)}); + pDispParams.setRgdispidNamedArgs(new DISPID[] {OaIdl.DISPID_PROPERTYPUT}); + // Visible-Prioperty + hr = ieDispatch.Invoke(dispIdVisible.getValue(), niid, lcid, propertyPutFlags, pDispParams, null, null, null); + COMUtils.checkRC(hr); + + // query for ConnectionPointContainer + Unknown unk = new Unknown(ieApp.getValue()); + PointerByReference ppCpc = new PointerByReference(); + hr = unk.QueryInterface(new REFIID(IID_IConnectionPointContainer), ppCpc); + COMUtils.checkRC(hr); + ConnectionPointContainer cpc = new ConnectionPointContainer(ppCpc.getValue()); + + // find connection point for DWebBrowserEvents2 + REFIID riid = new REFIID(IID_DWebBrowserEvents2); + PointerByReference ppCp = new PointerByReference(); + hr = cpc.FindConnectionPoint(riid, ppCp); + COMUtils.checkRC(hr); + final ConnectionPoint cp = new ConnectionPoint(ppCp.getValue()); + IID cp_iid = new IID(); + hr = cp.GetConnectionInterface(cp_iid); + COMUtils.checkRC(hr); + + final DWebBrowserEvents2_Listener listener = new DWebBrowserEvents2_Listener(); + final DWORDByReference pdwCookie = new DWORDByReference(); + HRESULT hr1 = cp.Advise(listener, pdwCookie); + COMUtils.checkRC(hr1); + + // Advise make several callbacks into the object passed in - at this + // point QueryInterface must have be called multiple times + Assert.assertTrue(listener.QueryInterface_called); + + // Call Navigate with URL https://github.com/java-native-access/jna + String navigateURL = "https://github.com/java-native-access/jna"; + String blockedURL = "http://www.google.de"; + + VARIANT[] arguments = new VARIANT[] {new VARIANT(navigateURL)}; + pDispParams = new DISPPARAMS.ByReference(); + pDispParams.setArgs(arguments); + hr = ieDispatch.Invoke(dispIdNavigate.getValue(), niid, lcid, methodFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + COMUtils.checkRC(hr, pExcepInfo, puArgErr); + + for (int i = 0; i < 10; i++) { + if (listener.navigateComplete2Called) { + break; + } + Thread.sleep(1000); + } + + // At this point the call to Navigate before should be complete + Assert.assertTrue(listener.navigateComplete2Called); + // Navidate complete should have brought us to github + Assert.assertEquals(navigateURL, listener.navigateComplete2String); + + listener.navigateComplete2Called = false; + listener.navigateComplete2String = null; + listener.blockNavigation = true; + + arguments = new VARIANT[]{new VARIANT(blockedURL)}; + pDispParams = new DISPPARAMS.ByReference(); + pDispParams.setArgs(arguments); + hr = ieDispatch.Invoke(dispIdNavigate.getValue(), niid, lcid, methodFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + COMUtils.checkRC(hr, pExcepInfo, puArgErr); + + // wait 10 seconds to ensure navigation won't happen + for (int i = 0; i < 10; i++) { + if (listener.navigateComplete2Called) { + break; + } + Thread.sleep(1000); + } + + // Naviation will be blocked - so NavigateComplete can't be called + Assert.assertFalse("NavigateComplete Handler was called although it should be blocked", listener.navigateComplete2Called); + } + +} diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/ComExceptionWithoutInitializationTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/ComExceptionWithoutInitializationTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/ComExceptionWithoutInitializationTest.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/ComExceptionWithoutInitializationTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,54 @@ +package com.sun.jna.platform.win32.COM; + +import com.sun.jna.platform.win32.Guid; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import org.junit.Test; + +public class ComExceptionWithoutInitializationTest { + + @Test + public void testCorrectExceptionOnFailedInitialization() { + String message = null; + try { + InternetExplorer ie = new InternetExplorer(); + } catch (COMException ex) { + message = ex.getMessage(); + } + + // This invocation must raise an exception, as the COM thread is not + // initialized, in the message it is expected, that the HRESULT is reported + // and the HRESULT resulting from calling into COM with it being initialized + // is 800401f0. The message is also expected to point the to correct + // initialization via CoInitialize + assertNotNull(message); + assertTrue(message.contains("HRESULT")); + assertTrue(message.contains("800401f0")); + assertTrue(message.contains("CoInitialize")); + } + + /** + * InternetExplorer / IWebBrowser2 - see + * http://msdn.microsoft.com/en-us/library/aa752127(v=vs.85).aspx + */ + private static class InternetExplorer extends COMLateBindingObject { + + public InternetExplorer(IDispatch iDispatch) { + super(iDispatch); + } + + public InternetExplorer() { + super(new Guid.CLSID("{0002DF01-0000-0000-C000-000000000046}"), true); + } + + /** + * IWebBrowser2::get_LocationURL
    + * Read-only COM property.
    + * + * @return the URL of the resource that is currently displayed. + */ + public String getURL() { + return getStringProperty("LocationURL"); + } + } +} diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/COMTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/COMTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/COMTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/COMTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -31,7 +31,11 @@ * @author dblock[at]dblock[dot]org */ public class COMTest extends TestCase { - + + static { + ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true); + } + public static void main(String[] args) { junit.textui.TestRunner.run(COMTest.class); } diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/COMUtilsTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/COMUtilsTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/COMUtilsTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/COMUtilsTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,18 +1,29 @@ package com.sun.jna.platform.win32.COM; -import junit.framework.TestCase; +import com.sun.jna.platform.win32.WinNT; +import org.junit.Test; -public class COMUtilsTest extends TestCase { +import static org.junit.Assert.*; +public class COMUtilsTest { + + @Test public void testSUCCEEDED() throws Exception { assertTrue(COMUtils.SUCCEEDED(COMUtils.S_OK)); assertTrue(COMUtils.SUCCEEDED(COMUtils.S_FALSE)); assertFalse(COMUtils.SUCCEEDED(COMUtils.E_UNEXPECTED)); } + @Test public void testFAILED() throws Exception { assertFalse(COMUtils.FAILED(COMUtils.S_OK)); assertFalse(COMUtils.FAILED(COMUtils.S_FALSE)); assertTrue(COMUtils.FAILED(COMUtils.E_UNEXPECTED)); } + + @Test(expected = COMException.class) + public void testCreateCOMExceptionFromCustomHRESULT() { + // This resulted in a LastErrorException instead of COMException + COMUtils.checkRC(new WinNT.HRESULT(0x80040200)); + } } \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/ConnectionPointContainer_Test.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/ConnectionPointContainer_Test.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/ConnectionPointContainer_Test.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/ConnectionPointContainer_Test.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,242 +0,0 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import com.sun.jna.Pointer; -import com.sun.jna.WString; -import com.sun.jna.platform.win32.Guid.CLSID; -import com.sun.jna.platform.win32.Guid.IID; -import com.sun.jna.platform.win32.Guid.REFIID; -import com.sun.jna.platform.win32.OaIdl; -import com.sun.jna.platform.win32.OaIdl.DISPID; -import com.sun.jna.platform.win32.OaIdl.DISPIDByReference; -import com.sun.jna.platform.win32.OaIdl.EXCEPINFO; -import com.sun.jna.platform.win32.OleAuto.DISPPARAMS; -import com.sun.jna.platform.win32.Guid; -import com.sun.jna.platform.win32.Kernel32; -import com.sun.jna.platform.win32.Ole32; -import com.sun.jna.platform.win32.OleAuto; -import com.sun.jna.platform.win32.Variant; -import com.sun.jna.platform.win32.WTypes; -import com.sun.jna.platform.win32.WinDef; -import com.sun.jna.platform.win32.WinError; -import com.sun.jna.platform.win32.Variant.VARIANT; -import com.sun.jna.platform.win32.WinDef.DWORDByReference; -import com.sun.jna.platform.win32.WinDef.LCID; -import com.sun.jna.platform.win32.WinDef.UINT; -import com.sun.jna.platform.win32.WinDef.UINTByReference; -import com.sun.jna.platform.win32.WinDef.WORD; -import com.sun.jna.platform.win32.WinNT.HRESULT; -import com.sun.jna.ptr.IntByReference; -import com.sun.jna.ptr.PointerByReference; - -public class ConnectionPointContainer_Test { - - PointerByReference ppWordApp; - - @Before - public void before() { - HRESULT hr = Ole32.INSTANCE.CoInitialize(null); - COMUtils.checkRC(hr); - - // Create word object - CLSID clsid = new CLSID("{000209FF-0000-0000-C000-000000000046}"); - this.ppWordApp = new PointerByReference(); - hr = Ole32.INSTANCE - .CoCreateInstance(clsid, null, WTypes.CLSCTX_SERVER, IDispatch.IID_IDISPATCH, this.ppWordApp); - COMUtils.checkRC(hr); - } - - @After - public void after() { - // Close Word - Dispatch d = new Dispatch(this.ppWordApp.getValue()); - DISPID dispIdMember = new DISPID(1105); // Quit - REFIID.ByValue riid = new REFIID.ByValue(Guid.IID_NULL); - LCID lcid = Kernel32.INSTANCE.GetSystemDefaultLCID(); - WinDef.WORD wFlags = new WinDef.WORD(1); - DISPPARAMS.ByReference pDispParams = new DISPPARAMS.ByReference(); - VARIANT.ByReference pVarResult = new VARIANT.ByReference(); - IntByReference puArgErr = new IntByReference(); - EXCEPINFO.ByReference pExcepInfo = new EXCEPINFO.ByReference(); - d.Invoke(dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); - - Ole32.INSTANCE.CoUninitialize(); - } - - @Test - public void queryInterface_ConnectionPointContainer() { - Unknown unk = new Unknown(this.ppWordApp.getValue()); - PointerByReference ppCpc = new PointerByReference(); - IID cpcIID = new IID("{B196B284-BAB4-101A-B69C-00AA00341D07}"); - HRESULT hr = unk.QueryInterface(new REFIID.ByValue(cpcIID), ppCpc); - COMUtils.checkRC(hr); - ConnectionPointContainer cpc = new ConnectionPointContainer(ppCpc.getValue()); - } - - @Test - public void FindConnectionPoint() { - // query for ConnectionPointContainer - Unknown unk = new Unknown(this.ppWordApp.getValue()); - PointerByReference ppCpc = new PointerByReference(); - IID cpcIID = new IID("{B196B284-BAB4-101A-B69C-00AA00341D07}"); - HRESULT hr = unk.QueryInterface(new REFIID.ByValue(cpcIID), ppCpc); - COMUtils.checkRC(hr); - ConnectionPointContainer cpc = new ConnectionPointContainer(ppCpc.getValue()); - - // find connection point for Application_Events4 - IID appEvnts4 = new IID("{00020A01-0000-0000-C000-000000000046}"); - REFIID riid = new REFIID(appEvnts4.getPointer()); - PointerByReference ppCp = new PointerByReference(); - hr = cpc.FindConnectionPoint(riid, ppCp); - COMUtils.checkRC(hr); - ConnectionPoint cp = new ConnectionPoint(ppCp.getValue()); - } - - @Test - public void GetConnectionInterface() { - // query for ConnectionPointContainer - Unknown unk = new Unknown(this.ppWordApp.getValue()); - PointerByReference ppCpc = new PointerByReference(); - IID cpcIID = new IID("{B196B284-BAB4-101A-B69C-00AA00341D07}"); - HRESULT hr = unk.QueryInterface(new REFIID.ByValue(cpcIID), ppCpc); - COMUtils.checkRC(hr); - ConnectionPointContainer cpc = new ConnectionPointContainer(ppCpc.getValue()); - - // find connection point for Application_Events4 - IID appEvnts4 = new IID("{00020A01-0000-0000-C000-000000000046}"); - REFIID riid = new REFIID(appEvnts4.getPointer()); - PointerByReference ppCp = new PointerByReference(); - hr = cpc.FindConnectionPoint(riid, ppCp); - COMUtils.checkRC(hr); - ConnectionPoint cp = new ConnectionPoint(ppCp.getValue()); - - IID cp_iid = new IID(); - hr = cp.GetConnectionInterface(cp_iid); - COMUtils.checkRC(hr); - - Assert.assertEquals(appEvnts4, cp_iid); - } - - class Application_Events4 implements IDispatchCallback { - public DispatchListener listener = new DispatchListener(this); - - @Override - public Pointer getPointer() { - return this.listener.getPointer(); - } - - //------------------------ IDispatch ------------------------------ - @Override - public HRESULT GetTypeInfoCount(UINTByReference pctinfo) { - return new HRESULT(WinError.E_NOTIMPL); - } - - @Override - public HRESULT GetTypeInfo(UINT iTInfo, LCID lcid, PointerByReference ppTInfo) { - return new HRESULT(WinError.E_NOTIMPL); - } - - @Override - public HRESULT GetIDsOfNames(REFIID.ByValue riid, WString[] rgszNames, int cNames, LCID lcid, DISPIDByReference rgDispId) { - return new HRESULT(WinError.E_NOTIMPL); - } - - public boolean Invoke_called = false; - @Override - public HRESULT Invoke(DISPID dispIdMember, REFIID.ByValue riid, LCID lcid, WORD wFlags, - DISPPARAMS.ByReference pDispParams, VARIANT.ByReference pVarResult, EXCEPINFO.ByReference pExcepInfo, - IntByReference puArgErr) { - this.Invoke_called = true; - return new HRESULT(WinError.E_NOTIMPL); - } - - - //------------------------ IUnknown ------------------------------ - public boolean QueryInterface_called = false; - @Override - public HRESULT QueryInterface(REFIID.ByValue refid, PointerByReference ppvObject) { - this.QueryInterface_called = true; - if (null==ppvObject) { - return new HRESULT(WinError.E_POINTER); - } - - String s = refid.toGuidString(); - IID appEvnts4 = new IID("{00020A01-0000-0000-C000-000000000046}"); - REFIID.ByValue riid = new REFIID.ByValue(appEvnts4.getPointer()); - - if (refid.equals(riid)) { - return WinError.S_OK; - } - - if (new Guid.IID(refid.getPointer()).equals(Unknown.IID_IUNKNOWN)) { - ppvObject.setValue(this.getPointer()); - return WinError.S_OK; - } - - if (new Guid.IID(refid.getPointer()).equals(Dispatch.IID_IDISPATCH)) { - ppvObject.setValue(this.getPointer()); - return WinError.S_OK; - } - - return new HRESULT(WinError.E_NOINTERFACE); - } - - public int AddRef() { - return 0; - } - - public int Release() { - return 0; - } - - } - - @Test - public void Advise() { - - // query for ConnectionPointContainer - Unknown unk = new Unknown(this.ppWordApp.getValue()); - PointerByReference ppCpc = new PointerByReference(); - IID cpcIID = new IID("{B196B284-BAB4-101A-B69C-00AA00341D07}"); - HRESULT hr = unk.QueryInterface(new REFIID.ByValue(cpcIID), ppCpc); - COMUtils.checkRC(hr); - ConnectionPointContainer cpc = new ConnectionPointContainer(ppCpc.getValue()); - - // find connection point for Application_Events4 - IID appEvnts4 = new IID("{00020A01-0000-0000-C000-000000000046}"); - REFIID riid = new REFIID(appEvnts4.getPointer()); - PointerByReference ppCp = new PointerByReference(); - hr = cpc.FindConnectionPoint(riid, ppCp); - COMUtils.checkRC(hr); - ConnectionPoint cp = new ConnectionPoint(ppCp.getValue()); - IID cp_iid = new IID(); - hr = cp.GetConnectionInterface(cp_iid); - COMUtils.checkRC(hr); - - Application_Events4 listener = new Application_Events4(); - - DWORDByReference pdwCookie = new DWORDByReference(); - hr = cp.Advise(listener, pdwCookie); - COMUtils.checkRC(hr); - - Assert.assertTrue(listener.QueryInterface_called); - - } - -} diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/EnumMoniker_Test.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/EnumMoniker_Test.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/EnumMoniker_Test.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/EnumMoniker_Test.java 2017-03-14 19:31:03.000000000 +0000 @@ -12,6 +12,7 @@ */ package com.sun.jna.platform.win32.COM; +import com.sun.jna.Pointer; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; @@ -25,7 +26,7 @@ import com.sun.jna.platform.win32.WinDef.ULONG; import com.sun.jna.platform.win32.WinDef.ULONGByReference; import com.sun.jna.platform.win32.WinNT.HRESULT; -import com.sun.jna.platform.win32.COM.util.Factory; +import com.sun.jna.platform.win32.COM.util.ObjectFactory; 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; @@ -33,7 +34,10 @@ import com.sun.jna.ptr.PointerByReference; public class EnumMoniker_Test { - + static { + ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true); + } + @ComInterface(iid="{00020970-0000-0000-C000-000000000046}") interface Application { @ComProperty @@ -50,25 +54,29 @@ interface MsWordApp extends Application { } - Factory factory; + ObjectFactory factory; MsWordApp ob1; MsWordApp ob2; @Before public void before() { - this.factory = new Factory(); + WinNT.HRESULT hr = Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED); + COMUtils.checkRC(hr); + + this.factory = new ObjectFactory(); // Two COM objects are require to be running for these tests to work this.ob1 = this.factory.createObject(MsWordApp.class); this.ob2 = this.factory.createObject(MsWordApp.class); - - WinNT.HRESULT hr = Ole32.INSTANCE.CoInitialize(null); - COMUtils.checkRC(hr); } @After public void after() { - ob1.Quit(); - ob2.Quit(); + if(ob1 != null) { + ob1.Quit(); + } + if(ob2 != null) { + ob2.Quit(); + } Ole32.INSTANCE.CoUninitialize(); } diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/IDispatchTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/IDispatchTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/IDispatchTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/IDispatchTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -18,7 +18,6 @@ import com.sun.jna.platform.win32.Guid.CLSID; import com.sun.jna.platform.win32.Guid.REFIID; import com.sun.jna.platform.win32.OaIdl.DISPIDByReference; -import com.sun.jna.platform.win32.OleAuto.DISPPARAMS; import com.sun.jna.platform.win32.Guid; import com.sun.jna.platform.win32.Kernel32; import com.sun.jna.platform.win32.Ole32; @@ -31,7 +30,10 @@ import com.sun.jna.ptr.PointerByReference; public class IDispatchTest extends TestCase { - + static { + ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true); + } + /** The Constant LOCALE_SYSTEM_DEFAULT. */ public final static LCID LOCALE_SYSTEM_DEFAULT = Kernel32.INSTANCE .GetSystemDefaultLCID(); @@ -40,7 +42,7 @@ try { PointerByReference pDispatch = new PointerByReference(); - // Get CLSID for Word.Application... + // Get CLSID for Shell.Application... CLSID.ByReference clsid = new CLSID.ByReference(); HRESULT hr = Ole32.INSTANCE.CLSIDFromProgID("Shell.Application", clsid); @@ -102,7 +104,7 @@ WString[] ptName = new WString[] { new WString("Application") }; DISPIDByReference pdispID = new DISPIDByReference(); - HRESULT hr = dispatch.GetIDsOfNames(new REFIID.ByValue(Guid.IID_NULL), ptName, 1, LOCALE_SYSTEM_DEFAULT, pdispID); + HRESULT hr = dispatch.GetIDsOfNames(new REFIID(Guid.IID_NULL), ptName, 1, LOCALE_SYSTEM_DEFAULT, pdispID); COMUtils.checkRC(hr); assertEquals(0, hr.intValue()); } diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/IShellFolderTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/IShellFolderTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/IShellFolderTest.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/IShellFolderTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,83 @@ +package com.sun.jna.platform.win32.COM; + +/* + * @author L W Ahonen, lwahonen@iki.fi + */ + +import junit.framework.TestCase; + + +import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.*; +import com.sun.jna.ptr.PointerByReference; + +public class IShellFolderTest extends TestCase { + static { + ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true); + } + + private IShellFolder psfMyComputer; + + public static WinNT.HRESULT BindToCsidl(int csidl, Guid.REFIID riid, PointerByReference ppv) { + WinNT.HRESULT hr; + PointerByReference pidl = new PointerByReference(); + hr = Shell32.INSTANCE.SHGetSpecialFolderLocation(null, csidl, pidl); + assertTrue(COMUtils.SUCCEEDED(hr)); + PointerByReference psfDesktopPTR = new PointerByReference(); + hr = Shell32.INSTANCE.SHGetDesktopFolder(psfDesktopPTR); + assertTrue(COMUtils.SUCCEEDED(hr)); + IShellFolder psfDesktop = IShellFolder.Converter.PointerToIShellFolder(psfDesktopPTR); + short cb = pidl.getValue().getShort(0); // See http://blogs.msdn.com/b/oldnewthing/archive/2011/08/30/10202076.aspx for explanation about this bit + if (cb != 0) { + hr = psfDesktop.BindToObject(pidl.getValue(), null, riid, ppv); + } else { + hr = psfDesktop.QueryInterface(riid, ppv); + } + psfDesktop.Release(); + Ole32.INSTANCE.CoTaskMemFree(pidl.getValue()); + return hr; + } + + public void setUp() throws Exception { + int CSIDL_DRIVES = 0x0011; + WinNT.HRESULT hr = Ole32.INSTANCE.CoInitialize(null); + assertTrue(COMUtils.SUCCEEDED(hr)); + PointerByReference psfMyComputerPTR = new PointerByReference(Pointer.NULL); + hr = BindToCsidl(CSIDL_DRIVES, new Guid.REFIID(IShellFolder.IID_ISHELLFOLDER), psfMyComputerPTR); + assertTrue(COMUtils.SUCCEEDED(hr)); + psfMyComputer = IShellFolder.Converter.PointerToIShellFolder(psfMyComputerPTR); + } + + public void tearDown() throws Exception { + psfMyComputer.Release(); + Ole32.INSTANCE.CoUninitialize(); + } + + public void testEnumObjects() throws Exception { + PointerByReference peidlPTR = new PointerByReference(); + int SHCONTF_FOLDERS = 0x20; + int SHCONTF_NONFOLDERS = 0x40; + boolean sawNames = false; + + WinNT.HRESULT hr = psfMyComputer.EnumObjects(null, + SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, peidlPTR); + assertTrue(COMUtils.SUCCEEDED(hr)); + IEnumIDList peidl = IEnumIDList.Converter.PointerToIEnumIDList(peidlPTR); + PointerByReference pidlItem = new PointerByReference(); + while (peidl.Next(1, pidlItem, null).intValue() == COMUtils.S_OK) { + PointerByReference sr = new PointerByReference(); + hr = psfMyComputer.GetDisplayNameOf(pidlItem.getValue(), 0, sr); + assertTrue(COMUtils.SUCCEEDED(hr)); + PointerByReference pszName = new PointerByReference(); + hr = Shlwapi.INSTANCE.StrRetToStr(sr, pidlItem.getValue(), pszName); + assertTrue(COMUtils.SUCCEEDED(hr)); + String wideString = pszName.getValue().getWideString(0); + if (wideString != null && wideString.length() > 0) + sawNames = true; + Ole32.INSTANCE.CoTaskMemFree(pszName.getValue()); + Ole32.INSTANCE.CoTaskMemFree(pidlItem.getValue()); + } + peidl.Release(); + assertTrue(sawNames); // We should see at least one item with a name + } +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/ITypeInfoTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/ITypeInfoTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/ITypeInfoTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/ITypeInfoTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -12,9 +12,6 @@ */ package com.sun.jna.platform.win32.COM; -import junit.framework.TestCase; - -import com.sun.jna.Native; import com.sun.jna.platform.win32.OaIdl.HREFTYPEByReference; import com.sun.jna.platform.win32.OaIdl.INVOKEKIND; import com.sun.jna.platform.win32.OaIdl.MEMBERID; @@ -29,28 +26,19 @@ import com.sun.jna.ptr.IntByReference; import com.sun.jna.ptr.PointerByReference; import org.junit.Ignore; +import org.junit.Test; + +import static org.junit.Assert.*; /** * @author dblock[at]dblock[dot]org */ -public class ITypeInfoTest extends TestCase { - - public static void main(String[] args) { - junit.textui.TestRunner.run(ITypeInfoTest.class); - } - - public ITypeInfoTest() { - } - - @Override - protected void setUp() throws Exception { - } - - @Override - protected void tearDown() throws Exception { +public class ITypeInfoTest { + static { + ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true); } - public ITypeInfo getTypeInfo() { + private ITypeInfo getTypeInfo() { TypeLibUtil shellTypeLib = new TypeLibUtil("{50A7E9B0-70EF-11D1-B75A-00A0C90564FE}", 1, 0); int typeInfoCount = shellTypeLib.getTypeInfoCount(); if (typeInfoCount == 0) @@ -59,7 +47,7 @@ return typeInfo; } - public ITypeInfo[] getTypeInfos() { + private ITypeInfo[] getTypeInfos() { TypeLibUtil shellTypeLib = new TypeLibUtil("{50A7E9B0-70EF-11D1-B75A-00A0C90564FE}", 1, 0); int typeInfoCount = shellTypeLib.getTypeInfoCount(); if (typeInfoCount == 0) @@ -83,6 +71,7 @@ public void testGetVarDesc() { } + @Test public void testGetNames() { ITypeInfo[] typeInfos = getTypeInfos(); MEMBERID memid = new MEMBERID(1); @@ -100,6 +89,7 @@ throw new RuntimeException("Didn't find name for member in any of the type infos"); } + @Test public void testGetRefTypeOfImplType() { ITypeInfo typeInfo = getTypeInfo(); HREFTYPEByReference pRefType = new HREFTYPEByReference(); @@ -110,6 +100,7 @@ //System.out.println("GetRefTypeOfImplType: " + pRefType.toString()); } + @Test public void testGetImplTypeFlags() { ITypeInfo typeInfo = getTypeInfo(); IntByReference pImplTypeFlags = new IntByReference(); @@ -120,6 +111,7 @@ //System.out.println("GetImplTypeFlags: " + pImplTypeFlags.toString()); } + @Test public void testGetIDsOfNames() { ITypeInfo[] typeInfos = getTypeInfos(); LPOLESTR[] rgszNames = {new LPOLESTR("Help")}; @@ -139,6 +131,7 @@ } + @Test public void testGetDocumentation() { ITypeInfo[] typeInfos = getTypeInfos(); MEMBERID memid = new MEMBERID(0); @@ -161,6 +154,7 @@ throw new RuntimeException("Didn't find documentation in any of the type infos"); } + @Test @Ignore("Needs a DLL that contains code") public void testGetDllEntry() { ITypeInfo[] typeInfos = getTypeInfos(); @@ -185,6 +179,7 @@ public void testGetRefTypeInfo() { } + @Test @Ignore("Needs a DLL that contains code") public void testAddressOfMember() { ITypeInfo[] typeInfos = getTypeInfos(); @@ -205,6 +200,7 @@ } + @Test public void testGetMops() { ITypeInfo typeInfo = getTypeInfo(); MEMBERID memid = new MEMBERID(0); diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/ITypeLibTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/ITypeLibTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/ITypeLibTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/ITypeLibTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -12,17 +12,22 @@ */ package com.sun.jna.platform.win32.COM; +import com.sun.jna.Native; +import com.sun.jna.Pointer; import junit.framework.TestCase; -import com.sun.jna.Native; import com.sun.jna.WString; import com.sun.jna.platform.win32.Guid.CLSID; +import com.sun.jna.platform.win32.Guid.GUID; import com.sun.jna.platform.win32.Kernel32; +import com.sun.jna.platform.win32.OaIdl; import com.sun.jna.platform.win32.OaIdl.MEMBERID; import com.sun.jna.platform.win32.OaIdl.TYPEKIND; import com.sun.jna.platform.win32.Ole32; import com.sun.jna.platform.win32.OleAuto; -import com.sun.jna.platform.win32.WTypes.BSTRByReference; +import com.sun.jna.platform.win32.WTypes; +import com.sun.jna.platform.win32.WTypes.BSTR; +import com.sun.jna.platform.win32.WinDef; import com.sun.jna.platform.win32.WinDef.LCID; import com.sun.jna.platform.win32.WinDef.UINT; import com.sun.jna.platform.win32.WinDef.ULONG; @@ -34,7 +39,16 @@ * @author dblock[at]dblock[dot]org */ public class ITypeLibTest extends TestCase { - + static { + ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true); + } + + // Microsoft Shell Controls And Automation + private static final String SHELL_CLSID = "{50A7E9B0-70EF-11D1-B75A-00A0C90564FE}"; + // Version 1.0 + private static final int SHELL_MAJOR = 1; + private static final int SHELL_MINOR = 0; + public static void main(String[] args) { junit.textui.TestRunner.run(ITypeLibTest.class); } @@ -43,22 +57,19 @@ } private ITypeLib loadShellTypeLib() { - // Microsoft Shell Controls And Automation CLSID.ByReference clsid = new CLSID.ByReference(); // get CLSID from string - HRESULT hr = Ole32.INSTANCE.CLSIDFromString(new WString( - "{50A7E9B0-70EF-11D1-B75A-00A0C90564FE}"), clsid); - COMUtils.checkRC(hr); - assertEquals(0, hr.intValue()); + HRESULT hr = Ole32.INSTANCE.CLSIDFromString(new WString(SHELL_CLSID), clsid); + assertTrue(COMUtils.SUCCEEDED(hr)); // get user default lcid LCID lcid = Kernel32.INSTANCE.GetUserDefaultLCID(); - // create a IUnknown pointer + PointerByReference pShellTypeLib = new PointerByReference(); // load typelib - hr = OleAuto.INSTANCE.LoadRegTypeLib(clsid, 1, 0, lcid, pShellTypeLib); - COMUtils.checkRC(hr); - assertEquals(0, hr.intValue()); + hr = OleAuto.INSTANCE.LoadRegTypeLib(clsid, SHELL_MAJOR, SHELL_MINOR, lcid, pShellTypeLib); + + assertTrue(COMUtils.SUCCEEDED(hr)); return new TypeLib(pShellTypeLib.getValue()); } @@ -66,7 +77,7 @@ public void testGetTypeInfoCount() { ITypeLib shellTypeLib = loadShellTypeLib(); UINT typeInfoCount = shellTypeLib.GetTypeInfoCount(); - //System.out.println("GetTypeInfoCount: " + typeInfoCount); + assertEquals(38, typeInfoCount.intValue()); } public void testGetTypeInfo() { @@ -75,8 +86,8 @@ PointerByReference ppTInfo = new PointerByReference(); HRESULT hr = shellTypeLib.GetTypeInfo(new UINT(0), ppTInfo); - COMUtils.checkRC(hr); - assertEquals(0, hr.intValue()); + assertTrue(COMUtils.SUCCEEDED(hr)); + //System.out.println("ITypeInfo: " + ppTInfo.toString()); } @@ -86,54 +97,119 @@ TYPEKIND.ByReference pTKind = new TYPEKIND.ByReference(); HRESULT hr = shellTypeLib.GetTypeInfoType(new UINT(0), pTKind); - COMUtils.checkRC(hr); - assertEquals(0, hr.intValue()); + assertTrue(COMUtils.SUCCEEDED(hr)); + //System.out.println("TYPEKIND: " + pTKind); } public void testGetTypeInfoOfGuid() { - // ITypeLib shellTypeLib = loadShellTypeLib(); - // - // GUID shellGuid = new GUID("{50A7E9B0-70EF-11D1-B75A-00A0C90564FE}"); - // TypeInfo.ByReference pTInfo = new TypeInfo.ByReference(); - // HRESULT hr = shellTypeLib.GetTypeInfoOfGuid(shellGuid, pTInfo); - // - // COMUtils.checkRC(hr); - // assertEquals(0, hr.intValue()); - // System.out.println("ITypeInfo: " + pTInfo.toString()); - } - - public void testGetLibAttr() { - // ITypeLib shellTypeLib = loadShellTypeLib(); - // - // TLIBATTR.ByReference ppTLibAttr = new TLIBATTR.ByReference(); - // HRESULT hr = shellTypeLib.GetLibAttr(ppTLibAttr); - // - // COMUtils.checkRC(hr); - // assertEquals(0, hr.intValue()); - // System.out.println("ppTLibAttr: " + ppTLibAttr.toString()); + ITypeLib shellTypeLib = loadShellTypeLib(); + + // GUID for dispinterface IFolderViewOC + GUID iFolderViewOC = new GUID("{9BA05970-F6A8-11CF-A442-00A0C90A8F39}"); + PointerByReference pbr = new PointerByReference(); + HRESULT hr = shellTypeLib.GetTypeInfoOfGuid(iFolderViewOC, pbr); + + assertTrue(COMUtils.SUCCEEDED(hr)); + } + + public void testLibAttr() { + ITypeLib shellTypeLib = loadShellTypeLib(); + + PointerByReference pbr = new PointerByReference(); + HRESULT hr = shellTypeLib.GetLibAttr(pbr); + + assertTrue(COMUtils.SUCCEEDED(hr)); + + OaIdl.TLIBATTR tlibAttr = new OaIdl.TLIBATTR(pbr.getValue()); + + assertEquals(SHELL_CLSID, tlibAttr.guid.toGuidString()); + assertEquals(SHELL_MAJOR, tlibAttr.wMajorVerNum.intValue()); + assertEquals(SHELL_MINOR, tlibAttr.wMinorVerNum.intValue()); + + shellTypeLib.ReleaseTLibAttr(tlibAttr); } public void testGetTypeComp() { - // ITypeLib shellTypeLib = loadShellTypeLib(); - // - // TypeComp.ByReference pTComp = new TypeComp.ByReference(); - // HRESULT hr = shellTypeLib.GetTypeComp(pTComp); - // - // COMUtils.checkRC(hr); - // assertEquals(0, hr.intValue()); - // System.out.println("pTComp: " + pTComp.toString()); + ITypeLib shellTypeLib = loadShellTypeLib(); + + PointerByReference pbr = new PointerByReference(); + HRESULT hr = shellTypeLib.GetTypeComp(pbr); + + // Only check that call works + assertTrue(COMUtils.SUCCEEDED(hr)); } + public void testIsName() { + ITypeLib shellTypeLib = loadShellTypeLib(); + + String memberValue = "Folder"; + Pointer p = Ole32.INSTANCE.CoTaskMemAlloc((memberValue.length() + 1L) * Native.WCHAR_SIZE); + WTypes.LPOLESTR olestr = new WTypes.LPOLESTR(p); + olestr.setValue(memberValue); + + WinDef.BOOLByReference boolByRef = new WinDef.BOOLByReference(); + + HRESULT hr = shellTypeLib.IsName(olestr, new ULONG(0), boolByRef); + assertTrue(COMUtils.SUCCEEDED(hr)); + + // Folder is a member + assertTrue(boolByRef.getValue().booleanValue()); + + Ole32.INSTANCE.CoTaskMemFree(p); + } + public void testFindName() { ITypeLib shellTypeLib = loadShellTypeLib(); - BSTRByReference szNameBuf = new BSTRByReference(OleAuto.INSTANCE.SysAllocString("Application")); + + // The found member is Count, search done with lowercase value to test + // correct behaviour (search is case insensitive) + String memberValue = "count"; + String memberValueOk = "Count"; + Pointer p = Ole32.INSTANCE.CoTaskMemAlloc((memberValue.length() + 1L) * Native.WCHAR_SIZE); + WTypes.LPOLESTR olestr = new WTypes.LPOLESTR(p); + olestr.setValue(memberValue); + + short maxResults = 100; + ULONG lHashVal = new ULONG(0); - USHORTByReference pcFound = new USHORTByReference((short)20); - - HRESULT hr = shellTypeLib.FindName(szNameBuf, lHashVal, null, null, pcFound); - - COMUtils.checkRC(hr); - //System.out.println("szNameBuf: " + szNameBuf); + USHORTByReference pcFound = new USHORTByReference(maxResults); + Pointer[] pointers = new Pointer[maxResults]; + MEMBERID[] rgMemId = new MEMBERID[maxResults]; + + HRESULT hr = shellTypeLib.FindName(olestr, lHashVal, pointers, rgMemId, pcFound); + assertTrue(COMUtils.SUCCEEDED(hr)); + + // If a reader can come up with more tests it would be appretiated, + // the documentation is unclear what more can be expected + + // 2 matches come from manual tests + assertTrue(pcFound.getValue().intValue() == 2); + // Check that function return corrected member name (Count) - see uppercase C + assertEquals(memberValueOk, olestr.getValue()); + + // There have to be as many pointers as reported by pcFound + assertNotNull(pointers[0]); + assertNotNull(pointers[1]); + assertNull(pointers[2]); // Might be flaky, contract only defined positions 0 -> (pcFound - 1) + + // Test access to second value + TypeInfo secondTypeInfo = new TypeInfo(pointers[1]); + + PointerByReference pbr = new PointerByReference(); + hr = secondTypeInfo.GetTypeAttr(pbr); + assertTrue(COMUtils.SUCCEEDED(hr)); + OaIdl.TYPEATTR pTypeAttr = new OaIdl.TYPEATTR(pbr.getValue()); + + // Either interface FolderItemVerbs ({1F8352C0-50B0-11CF-960C-0080C7F4EE85}) + // or FolderItems ({744129E0-CBE5-11CE-8350-444553540000}) + String typeGUID = pTypeAttr.guid.toGuidString(); + + assertTrue(typeGUID.equals("{1F8352C0-50B0-11CF-960C-0080C7F4EE85}") || + typeGUID.equals("{744129E0-CBE5-11CE-8350-444553540000}")); + + secondTypeInfo.ReleaseTypeAttr(pTypeAttr); + + Ole32.INSTANCE.CoTaskMemFree(olestr.getPointer()); } } diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/IUnknownTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/IUnknownTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/IUnknownTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/IUnknownTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -23,7 +23,10 @@ import com.sun.jna.ptr.PointerByReference; public class IUnknownTest extends TestCase { - + static { + ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true); + } + private Unknown createIUnknown() { try { PointerByReference pUnknown = new PointerByReference(); @@ -66,7 +69,7 @@ public void testQueryInterface() { Unknown iUnknown = this.createIUnknown(); PointerByReference ppvObject = new PointerByReference(); - iUnknown.QueryInterface(new REFIID.ByValue(IUnknown.IID_IUNKNOWN), ppvObject); + iUnknown.QueryInterface(new REFIID(IUnknown.IID_IUNKNOWN), ppvObject); assertTrue("ppvObject:" + ppvObject.toString(), ppvObject != null); } diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/RunningObjectTable_Test.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/RunningObjectTable_Test.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/RunningObjectTable_Test.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/RunningObjectTable_Test.java 2017-03-14 19:31:03.000000000 +0000 @@ -21,6 +21,7 @@ import com.sun.jna.platform.win32.Ole32; import com.sun.jna.platform.win32.Guid.REFIID; +import com.sun.jna.platform.win32.WTypes; import com.sun.jna.platform.win32.WTypes.BSTRByReference; import com.sun.jna.platform.win32.WinDef.DWORD; import com.sun.jna.platform.win32.WinDef.ULONG; @@ -30,7 +31,10 @@ import com.sun.jna.ptr.PointerByReference; public class RunningObjectTable_Test { - + static { + ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true); + } + @Before public void before() { HRESULT hr = Ole32.INSTANCE.CoInitialize(null); @@ -111,13 +115,8 @@ PointerByReference ppbc = new PointerByReference(); Ole32.INSTANCE.CreateBindCtx(new DWORD(), ppbc); - //IBindCtx pbc = new BindCtx(ppbc.getValue()); - - BSTRByReference ppszDisplayName = new BSTRByReference(); - hr = moniker.GetDisplayName(ppbc.getValue(), moniker.getPointer(), ppszDisplayName); - COMUtils.checkRC(hr); - String name = ppszDisplayName.getString(); - Ole32.INSTANCE.CoTaskMemFree(ppszDisplayName.getPointer().getPointer(0)); + + String name = moniker.GetDisplayName(ppbc.getValue(), moniker.getPointer()); PointerByReference ppunkObject = new PointerByReference(); hr = rot.GetObject(moniker.getPointer(), ppunkObject); @@ -125,7 +124,7 @@ IUnknown unk = new Unknown(ppunkObject.getValue()); PointerByReference ppvObject = new PointerByReference(); - hr = unk.QueryInterface(new REFIID.ByValue(IUnknown.IID_IUNKNOWN), ppvObject); + hr = unk.QueryInterface(new REFIID(IUnknown.IID_IUNKNOWN), ppvObject); assertEquals(0, hr.intValue()); assertNotNull(ppvObject.getValue()); diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/ShellApplicationWindowsTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/ShellApplicationWindowsTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/ShellApplicationWindowsTest.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/ShellApplicationWindowsTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,200 @@ +package com.sun.jna.platform.win32.COM; + +import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.Ole32; +import java.util.Iterator; +import java.util.NoSuchElementException; + +import com.sun.jna.platform.win32.Variant; +import com.sun.jna.platform.win32.Variant.VARIANT; +import com.sun.jna.platform.win32.WinDef.LONG; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.*; + +public class ShellApplicationWindowsTest { + + static { + ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true); + } + + @Before + public void setUp() throws Exception + { + Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED); + + // 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\""); + + // 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. + Thread.sleep(3000); + } + + @Test + public void testWindowsCount() + { + ShellApplication sa = new ShellApplication(); + + // IE is open, so there should be at least one present. + // More may exist if Windows Explorer windows are open. + assertTrue("No shell application windows found", + sa.Windows().Count() > 0); + + boolean pageFound = false; + for (InternetExplorer ie : sa.Windows()) + { + // For reasons unknown, Shell.Application.Windows can have null members inside it. + // All I care about is whether or not the collection contains the window I opened. + if (ie != null && "about:blank".equals(ie.getURL())) + { + pageFound = true; + } + } + + // Finally, did we find our page in the collection? + assertTrue("No IE page was found", pageFound); + + Ole32.INSTANCE.CoUninitialize(); + } + + @After + public void tearDown() throws Exception + { + Runtime.getRuntime().exec("taskkill.exe /f /im iexplore.exe"); + } + + /** + * A COM representation of the Windows shell. + */ + private static class ShellApplication extends COMLateBindingObject + { + public ShellApplication() throws COMException + { + super("Shell.Application", false); + } + + /** + * @return Creates and returns a ShellWindows object.
    + * This object represents a collection of all of the open windows that belong to the Shell. + */ + public ShellWindows Windows() + { + return new ShellWindows((IDispatch) invoke("Windows").getValue()); + } + + /** + * Represents a collection of the open windows that belong to the Shell.
    + * Methods associated with this objects can control and execute commands within the Shell, and obtain other Shell-related objects. + */ + public static class ShellWindows extends COMLateBindingObject implements Iterable + { + + private static class ShellWindowsIterator implements Iterator + { + + private ShellWindows source; + + private int count; + + private int max; + + public ShellWindowsIterator(ShellWindows collection) + { + source = collection; + max = source.Count(); + } + + @Override + public boolean hasNext() + { + return count < max; + } + + @Override + public InternetExplorer next() + { + if (!hasNext()) + { + throw new NoSuchElementException(); + } + return source.Item(count++); + } + + @Override + public void remove() + { + throw new UnsupportedOperationException(); + } + + } + + public ShellWindows(IDispatch iDispatch) + { + super(iDispatch); + } + + /** + * Retrieves an InternetExplorer object that represents the Shell window. + * + * @param idx + * The zero-based index of the item to retrieve.
    + * This value must be less than the value of the Count property. + * @return an InternetExplorer object that represents the Shell window. + */ + public InternetExplorer Item(int idx) + { + VARIANT arg = new VARIANT(); + arg.setValue(Variant.VT_I4, new LONG(idx)); + IDispatch result = (IDispatch) invoke("Item", arg).getValue(); + if (result == null) + { + return null; + } + return new InternetExplorer(result); + } + + /** + * @return the number of items in the collection. + */ + public int Count() + { + return getIntProperty("Count"); + } + + @SuppressWarnings({"unchecked", "rawtypes"}) + @Override + public Iterator iterator() + { + return new ShellWindowsIterator(this); + } + } + + } + + /** + * InternetExplorer / IWebBrowser2 - see http://msdn.microsoft.com/en-us/library/aa752127(v=vs.85).aspx + */ + private static class InternetExplorer extends COMLateBindingObject + { + + public InternetExplorer(IDispatch iDispatch) + { + super(iDispatch); + } + + /** + * IWebBrowser2::get_LocationURL
    + * Read-only COM property.
    + * + * @return the URL of the resource that is currently displayed. + */ + public String getURL() + { + return getStringProperty("LocationURL"); + } + } +} diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/TypeLibUtilTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/TypeLibUtilTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/TypeLibUtilTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/TypeLibUtilTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -15,15 +15,23 @@ import junit.framework.TestCase; import com.sun.jna.platform.win32.COM.TypeInfoUtil.TypeInfoDoc; +import com.sun.jna.platform.win32.COM.TypeLibUtil.FindName; +import com.sun.jna.platform.win32.COM.TypeLibUtil.IsName; +import com.sun.jna.platform.win32.OaIdl; import com.sun.jna.platform.win32.OaIdl.FUNCDESC; import com.sun.jna.platform.win32.OaIdl.MEMBERID; import com.sun.jna.platform.win32.OaIdl.TYPEATTR; +import com.sun.jna.platform.win32.WinNT.HRESULT; +import com.sun.jna.ptr.PointerByReference; /** * @author dblock[at]dblock[dot]org */ public class TypeLibUtilTest extends TestCase { - + static { + ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true); + } + public static void main(String[] args) { junit.textui.TestRunner.run(TypeLibUtilTest.class); } @@ -70,31 +78,52 @@ typeInfoUtil.ReleaseTypeAttr(typeAttr); } } - - public void testBug() { + + public void testFindName() { + // Test is modelled after ITypeLibTest#testFindName TypeLibUtil shellTypeLib = loadShellTypeLib(); - int typeInfoCount = shellTypeLib.getTypeInfoCount(); - ITypeInfo typeInfo = shellTypeLib.getTypeInfo(4); - TypeInfoUtil typeInfoUtil = new TypeInfoUtil(typeInfo); + String memberValue = "count"; + String memberValueOk = "Count"; - TYPEATTR typeAttr = typeInfoUtil.getTypeAttr(); - int cFuncs = typeAttr.cFuncs.intValue(); - - for (int y = 0; y < cFuncs; y++) { - // Get the function description - FUNCDESC funcDesc = typeInfoUtil.getFuncDesc(y); - // Get the member ID - MEMBERID memberID = funcDesc.memid; - // Get the name of the method - TypeInfoDoc typeInfoDoc2 = typeInfoUtil.getDocumentation(memberID); - String methodName = typeInfoDoc2.getName(); - - assertNotNull(methodName); - - typeInfoUtil.ReleaseFuncDesc(funcDesc); - } + FindName result = shellTypeLib.FindName(memberValue, 0, (short) 100); - typeInfoUtil.ReleaseTypeAttr(typeAttr); + // 2 matches come from manual tests + assertEquals(2, result.getFound()); + // Check that function return corrected member name (Count) - see uppercase C + assertEquals(memberValueOk, result.getNameBuf()); + + // There have to be as many pointers as reported by pcFound + ITypeInfo[] typelib = result.getTInfo(); + assertEquals(2, typelib.length); + assertNotNull(typelib[0]); + assertNotNull(typelib[1]); + + PointerByReference pbr = new PointerByReference(); + HRESULT hr = typelib[1].GetTypeAttr(pbr); + assertTrue(COMUtils.SUCCEEDED(hr)); + OaIdl.TYPEATTR pTypeAttr = new OaIdl.TYPEATTR(pbr.getValue()); + + // Either interface FolderItemVerbs ({1F8352C0-50B0-11CF-960C-0080C7F4EE85}) + // or FolderItems ({744129E0-CBE5-11CE-8350-444553540000}) + String typeGUID = pTypeAttr.guid.toGuidString(); + + assertTrue(typeGUID.equals("{1F8352C0-50B0-11CF-960C-0080C7F4EE85}") || + typeGUID.equals("{744129E0-CBE5-11CE-8350-444553540000}")); + + typelib[1].ReleaseTypeAttr(pTypeAttr); } + + public void testIsName() { + // Test is modelled after ITypeLibTest#testFindName + TypeLibUtil shellTypeLib = loadShellTypeLib(); + + String memberValue = "count"; + String memberValueOk = "Count"; + + IsName isNameResult = shellTypeLib.IsName(memberValue, 0); + + assertEquals(memberValueOk, isNameResult.getNameBuf()); + assertTrue(isNameResult.isName()); + } } diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacks2_Test.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacks2_Test.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacks2_Test.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacks2_Test.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,287 @@ +package com.sun.jna.platform.win32.COM.util; + +import com.sun.jna.Pointer; +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.ComObject; +import com.sun.jna.platform.win32.Ole32; +import com.sun.jna.platform.win32.Variant; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class ComEventCallbacks2_Test { + + static { + ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true); + } + + Factory factory; + + @Before + public void before() { + Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED); + this.factory = new Factory(); + } + + @After + public void after() { + this.factory.disposeAll(); + Ole32.INSTANCE.CoUninitialize(); + } + + @Test + public void testFireCloseHandlerMatching() throws InterruptedException { + + class ApplicatonEventsHandler extends AbstractComEventCallbackListener implements ApplicationEvents4ListenerMatching { + + public volatile boolean changed = false; + public volatile boolean beforeClose = false; + public volatile boolean error = false; + + @Override + public void errorReceivingCallbackEvent(String string, Exception excptn) { + if(string.startsWith("No method found with")) { + return; // Normal case + } + System.out.println("Error: " + string); + error = true; + } + + public void DocumentChange() { + changed = true; + } + + public void DocumentBeforeClose(IDispatch Doc, Variant.VARIANT Cancel) { + beforeClose = true; + } + } + + ApplicatonEventsHandler handler = new ApplicatonEventsHandler(); + + Application appX = factory.createObject(Application.class); + + Thread.sleep(500); + + IComEventCallbackCookie cookie = appX.advise(ApplicationEvents4ListenerMatching.class, handler); + + IDispatch doc = appX.getProperty(IDispatch.class, "Documents").invokeMethod(IDispatch.class, "Add"); + + Thread.sleep(500); + + doc.getProperty(IDispatch.class, "Paragraphs") + .invokeMethod(IDispatch.class, "Item", 1) + .getProperty(IDispatch.class, "Range") + .setProperty("Text", "Test text"); + + Thread.sleep(500); + + doc.invokeMethod(Void.class, "Close", Boolean.FALSE); + + Thread.sleep(500); + + appX.unadvise(ApplicationEvents4ListenerMatching.class, cookie); + + appX.invokeMethod(Void.class, "Quit", Boolean.FALSE); + + Assert.assertTrue(handler.changed); + Assert.assertTrue(handler.beforeClose); + Assert.assertFalse(handler.error); + } + + @Test + public void testFireCloseHandlerLessArguments() throws InterruptedException { + + class ApplicatonEventsHandler extends AbstractComEventCallbackListener implements ApplicationEvents4ListenerLessArguments { + + public volatile boolean changed = false; + public volatile boolean beforeClose = false; + public volatile boolean error = false; + + @Override + public void errorReceivingCallbackEvent(String string, Exception excptn) { + if(string.startsWith("No method found with")) { + return; // Normal case + } + System.out.println("Error: " + string); + if(excptn != null) { + System.out.println(excptn.getMessage()); + excptn.printStackTrace(System.out); + } + error = true; + } + + public void DocumentChange() { + changed = true; + } + + public void DocumentBeforeClose() { + beforeClose = true; + } + } + + ApplicatonEventsHandler handler = new ApplicatonEventsHandler(); + + Application appX = factory.createObject(Application.class); + + Thread.sleep(500); + + IComEventCallbackCookie cookie = appX.advise(ApplicationEvents4ListenerLessArguments.class, handler); + + IDispatch doc = appX.getProperty(IDispatch.class, "Documents").invokeMethod(IDispatch.class, "Add"); + + Thread.sleep(500); + + doc.getProperty(IDispatch.class, "Paragraphs") + .invokeMethod(IDispatch.class, "Item", 1) + .getProperty(IDispatch.class, "Range") + .setProperty("Text", "Test text"); + + Thread.sleep(500); + + doc.invokeMethod(Void.class, "Close", Boolean.FALSE); + + Thread.sleep(500); + + appX.unadvise(ApplicationEvents4ListenerMatching.class, cookie); + + appX.invokeMethod(Void.class, "Quit", Boolean.FALSE); + + Assert.assertTrue(handler.changed); + Assert.assertTrue(handler.beforeClose); + Assert.assertFalse(handler.error); + } + + @Test + public void testFireCloseHandlerMoreArguments() throws InterruptedException { + + class ApplicatonEventsHandler extends AbstractComEventCallbackListener implements ApplicationEvents4ListenerMoreArguments { + + public volatile boolean changed = false; + public volatile boolean beforeClose = false; + public volatile boolean error = false; + public volatile boolean fakeArgumentObjectWasNull = false; + public volatile boolean fakeArgumentIntWas0 = false; + + @Override + public void errorReceivingCallbackEvent(String string, Exception excptn) { + if(string.startsWith("No method found with")) { + return; // Normal case + } + System.out.println("Error: " + string); + if(excptn != null) { + System.out.println(excptn.getMessage()); + excptn.printStackTrace(System.out); + } + error = true; + } + + public void DocumentChange() { + changed = true; + } + + public void DocumentBeforeClose(IDispatch Doc, Variant.VARIANT Cancel, Boolean fakeArgumentObject, int fakeArgumentInt) { + beforeClose = true; + fakeArgumentObjectWasNull = fakeArgumentObject == null; + fakeArgumentIntWas0 = fakeArgumentInt == 0; + } + } + + ApplicatonEventsHandler handler = new ApplicatonEventsHandler(); + + Application appX = factory.createObject(Application.class); + + Thread.sleep(500); + + IComEventCallbackCookie cookie = appX.advise(ApplicationEvents4ListenerMoreArguments.class, handler); + + IDispatch doc = appX.getProperty(IDispatch.class, "Documents").invokeMethod(IDispatch.class, "Add"); + + Thread.sleep(500); + + doc.getProperty(IDispatch.class, "Paragraphs") + .invokeMethod(IDispatch.class, "Item", 1) + .getProperty(IDispatch.class, "Range") + .setProperty("Text", "Test text"); + + Thread.sleep(500); + + doc.invokeMethod(Void.class, "Close", Boolean.FALSE); + + Thread.sleep(500); + + appX.unadvise(ApplicationEvents4ListenerMatching.class, cookie); + + appX.invokeMethod(Void.class, "Quit", Boolean.FALSE); + + Assert.assertTrue(handler.changed); + Assert.assertTrue(handler.beforeClose); + Assert.assertFalse(handler.error); + Assert.assertTrue(handler.fakeArgumentIntWas0); + Assert.assertTrue(handler.fakeArgumentObjectWasNull); + } + + + @ComInterface(iid="{00020A01-0000-0000-C000-000000000046}") + interface ApplicationEvents4ListenerMatching { + + /** + *

    + * id(0x3)

    + */ + @ComEventCallback(dispid = 0x3) + void DocumentChange(); + + /** + *

    + * id(0x6)

    + */ + @ComEventCallback(dispid = 0x6) + void DocumentBeforeClose(IDispatch Doc, Variant.VARIANT Cancel); + } + + @ComInterface(iid="{00020A01-0000-0000-C000-000000000046}") + interface ApplicationEvents4ListenerLessArguments { + + /** + *

    + * id(0x3)

    + */ + @ComEventCallback(dispid = 0x3) + void DocumentChange(); + + /** + *

    + * id(0x6)

    + */ + @ComEventCallback(dispid = 0x6) + void DocumentBeforeClose(); + } + + @ComInterface(iid="{00020A01-0000-0000-C000-000000000046}") + interface ApplicationEvents4ListenerMoreArguments { + + /** + *

    + * id(0x3)

    + */ + @ComEventCallback(dispid = 0x3) + void DocumentChange(); + + /** + *

    + * id(0x6)

    + */ + @ComEventCallback(dispid = 0x6) + void DocumentBeforeClose(IDispatch Doc, Variant.VARIANT Cancel, Boolean fakeArgumentObject, int fakeArgumentInt); + } + + @ComObject(clsId = "{000209FF-0000-0000-C000-000000000046}") + public interface Application extends + IDispatch, + IConnectionPoint, + IUnknown { + + } +} diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacksFactory_Test.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacksFactory_Test.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacksFactory_Test.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacksFactory_Test.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,298 @@ +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ +package com.sun.jna.platform.win32.COM.util; + +import com.sun.jna.platform.win32.AbstractWin32TestSupport; +import com.sun.jna.platform.win32.COM.COMUtils; +import org.junit.After; +import org.junit.Assert; +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; +import com.sun.jna.platform.win32.COM.util.annotation.ComProperty; +import com.sun.jna.platform.win32.Guid.IID; +import com.sun.jna.platform.win32.Guid.REFIID; +import com.sun.jna.platform.win32.OaIdl; +import com.sun.jna.platform.win32.Variant; +import com.sun.jna.platform.win32.Variant.VARIANT; +import com.sun.jna.platform.win32.WinNT.HRESULT; +import com.sun.jna.ptr.PointerByReference; +import org.hamcrest.CoreMatchers; + +import static com.sun.jna.platform.win32.COM.IUnknown.IID_IUNKNOWN; +import static com.sun.jna.platform.win32.COM.IDispatch.IID_IDISPATCH; +import static org.junit.Assert.*; + +public class ComEventCallbacksFactory_Test { + + static { + ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true); + } + + Factory factory; + + @Before + public void before() { + AbstractWin32TestSupport.killProcessByName("iexplore.exe"); + try { + Thread.sleep(5 * 1000); + } catch (InterruptedException ex) {} + + ComThread thread = new ComThread("Default Factory COM Thread", 10000, new Thread.UncaughtExceptionHandler() { + @Override + public void uncaughtException(Thread t, Throwable e) { + //ignore + } + }); + this.factory = new Factory(thread); + } + + @After + public void after() { + this.factory.disposeAll(); + this.factory.getComThread().terminate(10000); + } + + + @ComObject(progId="Internet.Explorer.1", clsId = "{0002DF01-0000-0000-C000-000000000046}") + interface ComInternetExplorer extends ComIWebBrowser2 { + } + + @ComInterface(iid="{D30C1661-CDAF-11D0-8A3E-00C04FC9E26E}") + interface ComIWebBrowser2 extends IUnknown, IConnectionPoint { + @ComProperty + boolean getVisible(); + + @ComProperty + void setVisible(boolean value); + + @ComMethod + void Quit(); + + @ComMethod + /** + * navOpenInNewWindow = 1 + * navNoHistory = 2 + * navNoReadFromCache = 4 + * navNoWriteToCache = 8 + * navAllowAutosearch = 16 + * navBrowserBar = 32 + * navHyperlink = 64 + * navEnforceRestricted = 128 + * navNewWindowsManaged = 256 + * navUntrustedForDownload = 512 + * navTrustedForActiveX = 1024 + * navOpenInNewTab = 2048 + * navOpenInBackgroundTab = 4096 + * navKeepWordWheelText = 8192 + * navVirtualTab = 16384 + * navBlockRedirectsXDomain = 32768 + * navOpenNewForegroundTab = 65536 + */ + void Navigate(String url, long flags, String targetFrameName, VARIANT postData, String headers); + } + + @ComInterface(iid=DWebBrowserEvents2.IID) + interface DWebBrowserEvents2 { + public static final String IID = "{34A715A0-6587-11D0-924A-0020AFC7AC4D}"; + + @ComEventCallback(dispid=0x000000fd) + void OnQuit(); + + @ComEventCallback(dispid=0x000000fc) + void NavigateComplete2(IUnknown source, Object url); + + @ComEventCallback(dispid=0x000000fa) + void BeforeNavigate2(IUnknown pDisp, + String URL, + long Flags, + String TargetFrameName, + VARIANT.ByReference PostData, + VARIANT.ByReference Headers, + OaIdl.VARIANT_BOOLByReference Cancel); + } + + class DWebBrowserEvents2_Listener extends AbstractComEventCallbackListener implements DWebBrowserEvents2 { + + @Override + public void errorReceivingCallbackEvent(String message, Exception exception) { +// System.err.println(message); +// if(exception != null) { +// System.err.println(exception.getMessage()); +// exception.printStackTrace(System.err); +// } + } + + volatile boolean blockNavigate = false; + + public void BeforeNavigate2( + IUnknown pDisp, + String URL, + long Flags, + String TargetFrameName, + VARIANT.ByReference PostData, + VARIANT.ByReference Headers, + OaIdl.VARIANT_BOOLByReference Cancel) { + // The utilizing unittest is adviseBeforeNavigate + if(blockNavigate){ + Cancel.setValue(Variant.VARIANT_TRUE); + } + } + + volatile boolean navigateComplete2Called = false; + volatile String navigateComplete2URL = null; + @Override + public void NavigateComplete2( IUnknown source, Object url) { + navigateComplete2Called = true; + if(url != null) { + navigateComplete2URL = url.toString(); + } + } + + volatile Boolean Quit_called = null; + @Override + public void OnQuit() { + Quit_called = true; + } + } + + @Test + public void advise_Quit() throws InterruptedException { + ComInternetExplorer ieApp = factory.createObject(ComInternetExplorer.class); + ComIWebBrowser2 iWebBrowser2 = ieApp.queryInterface(ComIWebBrowser2.class); + iWebBrowser2.setVisible(true); + DWebBrowserEvents2_Listener listener = new DWebBrowserEvents2_Listener(); + iWebBrowser2.advise(DWebBrowserEvents2.class, listener); + + iWebBrowser2.Quit(); + + //Wait for event to happen + Thread.sleep(200); + + Assert.assertNotNull(listener.Quit_called); + Assert.assertTrue(listener.Quit_called); + } + + @Test + public void unadvise_Quit() throws InterruptedException { + ComInternetExplorer ieApp = factory.createObject(ComInternetExplorer.class); + ComIWebBrowser2 iWebBrowser2 = ieApp.queryInterface(ComIWebBrowser2.class); + iWebBrowser2.setVisible(true); + + DWebBrowserEvents2_Listener listener = new DWebBrowserEvents2_Listener(); + IComEventCallbackCookie cookie = iWebBrowser2.advise(DWebBrowserEvents2.class, listener); + + iWebBrowser2.unadvise(DWebBrowserEvents2.class, cookie); + listener.Quit_called=false; + + iWebBrowser2.Quit(); + + Thread.sleep(200); + + Assert.assertNotNull(listener.Quit_called); + Assert.assertFalse(listener.Quit_called); + } + + @Test + public void adviseNavigateComplete2() throws InterruptedException { + ComInternetExplorer ieApp = factory.createObject(ComInternetExplorer.class); + ComIWebBrowser2 iWebBrowser2 = ieApp.queryInterface(ComIWebBrowser2.class); + iWebBrowser2.setVisible(true); + + DWebBrowserEvents2_Listener listener = new DWebBrowserEvents2_Listener(); + IComEventCallbackCookie cookie = iWebBrowser2.advise(DWebBrowserEvents2.class, listener); + + iWebBrowser2.Navigate("https://github.com/java-native-access/jna", 0, null, null, null); + + for(int i = 0; i < 10; i++) { + if(listener.navigateComplete2Called) { + break; + } + Thread.sleep(1000); + } + + iWebBrowser2.Quit(); + + Assert.assertTrue("NavigateComplete was not called", listener.navigateComplete2Called); + Assert.assertNotNull("URL passed to NavigateComplete2 was NULL", listener.navigateComplete2URL); + Assert.assertThat(listener.navigateComplete2URL, CoreMatchers.startsWith("https://github.com/java-native-access/jna")); + } + + @Test + public void adviseBeforeNavigate() throws InterruptedException { + ComInternetExplorer ieApp = factory.createObject(ComInternetExplorer.class); + ComIWebBrowser2 iWebBrowser2 = ieApp.queryInterface(ComIWebBrowser2.class); + iWebBrowser2.setVisible(true); + + DWebBrowserEvents2_Listener listener = new DWebBrowserEvents2_Listener(); + IComEventCallbackCookie cookie = iWebBrowser2.advise(DWebBrowserEvents2.class, listener); + + listener.blockNavigate = true; + + iWebBrowser2.Navigate("https://github.com/java-native-access/jna", 0, null, null, null); + + for(int i = 0; i < 10; i++) { + if(listener.navigateComplete2Called) { + break; + } + Thread.sleep(1000); + } + + iWebBrowser2.Quit(); + + // NavigateComplete can't be called if access is blocked + Assert.assertFalse("Navigation to https://github.com/java-native-access/jna should be blocked", listener.navigateComplete2Called); + } + + @Test + public void testComEventCallback() { + DWebBrowserEvents2_Listener listener = new DWebBrowserEvents2_Listener(); + CallbackProxy proxy = new CallbackProxy(factory, DWebBrowserEvents2.class, listener); + + REFIID refiid = new REFIID(new IID(DWebBrowserEvents2.IID)); + + // precondition: the structures for the listenedToRiid and + // refiid have to be different (else the PointerType#equals would + // be enough + assertFalse(proxy.listenedToRiid.getPointer().equals(refiid.getPointer())); + + // Neverthe less, the QueryInterface method has to return the + // correct pointer (the IID is relevant, not its wrapper + PointerByReference interfacePointer = new PointerByReference(); + + // Check the "business" interface + HRESULT hr = proxy.QueryInterface(refiid, interfacePointer); + assertTrue(COMUtils.SUCCEEDED(hr)); + assertEquals(interfacePointer.getValue(), proxy.getPointer()); + + // IUnknown must be implemented + hr = proxy.QueryInterface(new REFIID(IID_IUNKNOWN), interfacePointer); + assertTrue(COMUtils.SUCCEEDED(hr)); + assertEquals(interfacePointer.getValue(), proxy.getPointer()); + + // Currently only Dispatch based callbacks are supported, + // so this interface must be present to + hr = proxy.QueryInterface(new REFIID(IID_IDISPATCH), interfacePointer); + assertTrue(COMUtils.SUCCEEDED(hr)); + assertEquals(interfacePointer.getValue(), proxy.getPointer()); + + // Negative check -- this has to fail, the IID should not be + // assigned + hr = proxy.QueryInterface(new REFIID(new IID("{00000000-0000-0000-C000-000000000000}")), interfacePointer); + assertTrue(COMUtils.FAILED(hr)); + } +} diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacksObjectFactory_Test.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacksObjectFactory_Test.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacksObjectFactory_Test.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacksObjectFactory_Test.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,294 @@ +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ +package com.sun.jna.platform.win32.COM.util; + +import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.AbstractWin32TestSupport; +import com.sun.jna.platform.win32.COM.COMUtils; +import org.junit.After; +import org.junit.Assert; +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; +import com.sun.jna.platform.win32.COM.util.annotation.ComProperty; +import com.sun.jna.platform.win32.Guid.IID; +import com.sun.jna.platform.win32.Guid.REFIID; +import com.sun.jna.platform.win32.OaIdl; +import com.sun.jna.platform.win32.Ole32; +import com.sun.jna.platform.win32.Variant; +import com.sun.jna.platform.win32.Variant.VARIANT; +import com.sun.jna.platform.win32.WinNT.HRESULT; +import com.sun.jna.ptr.PointerByReference; +import org.hamcrest.CoreMatchers; + +import static com.sun.jna.platform.win32.COM.IUnknown.IID_IUNKNOWN; +import static com.sun.jna.platform.win32.COM.IDispatch.IID_IDISPATCH; +import static org.junit.Assert.*; + +public class ComEventCallbacksObjectFactory_Test { + + static { + ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true); + } + + ObjectFactory factory; + + @Before + public void before() { + AbstractWin32TestSupport.killProcessByName("iexplore.exe"); + try { + Thread.sleep(5 * 1000); + } catch (InterruptedException ex) {} + Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED); + this.factory = new ObjectFactory(); + } + + @After + public void after() { + this.factory.disposeAll(); + Ole32.INSTANCE.CoUninitialize(); + } + + + @ComObject(progId="Internet.Explorer.1", clsId = "{0002DF01-0000-0000-C000-000000000046}") + interface ComInternetExplorer extends ComIWebBrowser2 { + } + + @ComInterface(iid="{D30C1661-CDAF-11D0-8A3E-00C04FC9E26E}") + interface ComIWebBrowser2 extends IUnknown, IConnectionPoint { + @ComProperty + boolean getVisible(); + + @ComProperty + void setVisible(boolean value); + + @ComMethod + void Quit(); + + @ComMethod + /** + * navOpenInNewWindow = 1 + * navNoHistory = 2 + * navNoReadFromCache = 4 + * navNoWriteToCache = 8 + * navAllowAutosearch = 16 + * navBrowserBar = 32 + * navHyperlink = 64 + * navEnforceRestricted = 128 + * navNewWindowsManaged = 256 + * navUntrustedForDownload = 512 + * navTrustedForActiveX = 1024 + * navOpenInNewTab = 2048 + * navOpenInBackgroundTab = 4096 + * navKeepWordWheelText = 8192 + * navVirtualTab = 16384 + * navBlockRedirectsXDomain = 32768 + * navOpenNewForegroundTab = 65536 + */ + void Navigate(String url, long flags, String targetFrameName, VARIANT postData, String headers); + } + + @ComInterface(iid=DWebBrowserEvents2.IID) + interface DWebBrowserEvents2 { + public static final String IID = "{34A715A0-6587-11D0-924A-0020AFC7AC4D}"; + + @ComEventCallback(dispid=0x000000fd) + void OnQuit(); + + @ComEventCallback(dispid=0x000000fc) + void NavigateComplete2(IUnknown source, Object url); + + @ComEventCallback(dispid=0x000000fa) + void BeforeNavigate2(IUnknown pDisp, + String URL, + long Flags, + String TargetFrameName, + VARIANT.ByReference PostData, + VARIANT.ByReference Headers, + OaIdl.VARIANT_BOOLByReference Cancel); + } + + class DWebBrowserEvents2_Listener extends AbstractComEventCallbackListener implements DWebBrowserEvents2 { + + @Override + public void errorReceivingCallbackEvent(String message, Exception exception) { +// System.err.println(message); +// if(exception != null) { +// System.err.println(exception.getMessage()); +// exception.printStackTrace(System.err); +// } + } + + volatile boolean blockNavigate = false; + + public void BeforeNavigate2( + IUnknown pDisp, + String URL, + long Flags, + String TargetFrameName, + VARIANT.ByReference PostData, + VARIANT.ByReference Headers, + OaIdl.VARIANT_BOOLByReference Cancel) { + // The utilizing unittest is adviseBeforeNavigate + if(blockNavigate){ + Cancel.setValue(Variant.VARIANT_TRUE); + } + } + + volatile boolean navigateComplete2Called = false; + volatile String navigateComplete2URL = null; + @Override + public void NavigateComplete2( IUnknown source, Object url) { + navigateComplete2Called = true; + if(url != null) { + navigateComplete2URL = url.toString(); + } + } + + volatile Boolean Quit_called = null; + @Override + public void OnQuit() { + Quit_called = true; + } + } + + @Test + public void advise_Quit() throws InterruptedException { + ComInternetExplorer ieApp = factory.createObject(ComInternetExplorer.class); + ComIWebBrowser2 iWebBrowser2 = ieApp.queryInterface(ComIWebBrowser2.class); + iWebBrowser2.setVisible(true); + DWebBrowserEvents2_Listener listener = new DWebBrowserEvents2_Listener(); + iWebBrowser2.advise(DWebBrowserEvents2.class, listener); + + iWebBrowser2.Quit(); + + //Wait for event to happen + Thread.sleep(200); + + Assert.assertNotNull(listener.Quit_called); + Assert.assertTrue(listener.Quit_called); + } + + @Test + public void unadvise_Quit() throws InterruptedException { + ComInternetExplorer ieApp = factory.createObject(ComInternetExplorer.class); + ComIWebBrowser2 iWebBrowser2 = ieApp.queryInterface(ComIWebBrowser2.class); + iWebBrowser2.setVisible(true); + + DWebBrowserEvents2_Listener listener = new DWebBrowserEvents2_Listener(); + IComEventCallbackCookie cookie = iWebBrowser2.advise(DWebBrowserEvents2.class, listener); + + iWebBrowser2.unadvise(DWebBrowserEvents2.class, cookie); + listener.Quit_called=false; + + iWebBrowser2.Quit(); + + Thread.sleep(200); + + Assert.assertNotNull(listener.Quit_called); + Assert.assertFalse(listener.Quit_called); + } + + @Test + public void adviseNavigateComplete2() throws InterruptedException { + ComInternetExplorer ieApp = factory.createObject(ComInternetExplorer.class); + ComIWebBrowser2 iWebBrowser2 = ieApp.queryInterface(ComIWebBrowser2.class); + iWebBrowser2.setVisible(true); + + DWebBrowserEvents2_Listener listener = new DWebBrowserEvents2_Listener(); + IComEventCallbackCookie cookie = iWebBrowser2.advise(DWebBrowserEvents2.class, listener); + + iWebBrowser2.Navigate("https://github.com/java-native-access/jna", 0, null, null, null); + + for(int i = 0; i < 10; i++) { + if(listener.navigateComplete2Called) { + break; + } + Thread.sleep(1000); + } + + iWebBrowser2.Quit(); + + Assert.assertTrue("NavigateComplete was not called", listener.navigateComplete2Called); + Assert.assertNotNull("URL passed to NavigateComplete2 was NULL", listener.navigateComplete2URL); + Assert.assertThat(listener.navigateComplete2URL, CoreMatchers.startsWith("https://github.com/java-native-access/jna")); + } + + @Test + public void adviseBeforeNavigate() throws InterruptedException { + ComInternetExplorer ieApp = factory.createObject(ComInternetExplorer.class); + ComIWebBrowser2 iWebBrowser2 = ieApp.queryInterface(ComIWebBrowser2.class); + iWebBrowser2.setVisible(true); + + DWebBrowserEvents2_Listener listener = new DWebBrowserEvents2_Listener(); + IComEventCallbackCookie cookie = iWebBrowser2.advise(DWebBrowserEvents2.class, listener); + + listener.blockNavigate = true; + + iWebBrowser2.Navigate("https://github.com/java-native-access/jna", 0, null, null, null); + + for(int i = 0; i < 10; i++) { + if(listener.navigateComplete2Called) { + break; + } + Thread.sleep(1000); + } + + iWebBrowser2.Quit(); + + // NavigateComplete can't be called if access is blocked + Assert.assertFalse("Navigation to https://github.com/java-native-access/jna should be blocked", listener.navigateComplete2Called); + } + + @Test + public void testComEventCallback() { + DWebBrowserEvents2_Listener listener = new DWebBrowserEvents2_Listener(); + CallbackProxy proxy = new CallbackProxy(factory, DWebBrowserEvents2.class, listener); + + REFIID refiid = new REFIID(new IID(DWebBrowserEvents2.IID)); + + // precondition: the structures for the listenedToRiid and + // refiid have to be different (else the PointerType#equals would + // be enough + assertFalse(proxy.listenedToRiid.getPointer().equals(refiid.getPointer())); + + // Neverthe less, the QueryInterface method has to return the + // correct pointer (the IID is relevant, not its wrapper + PointerByReference interfacePointer = new PointerByReference(); + + // Check the "business" interface + HRESULT hr = proxy.QueryInterface(refiid, interfacePointer); + assertTrue(COMUtils.SUCCEEDED(hr)); + assertEquals(interfacePointer.getValue(), proxy.getPointer()); + + // IUnknown must be implemented + hr = proxy.QueryInterface(new REFIID(IID_IUNKNOWN), interfacePointer); + assertTrue(COMUtils.SUCCEEDED(hr)); + assertEquals(interfacePointer.getValue(), proxy.getPointer()); + + // Currently only Dispatch based callbacks are supported, + // so this interface must be present to + hr = proxy.QueryInterface(new REFIID(IID_IDISPATCH), interfacePointer); + assertTrue(COMUtils.SUCCEEDED(hr)); + assertEquals(interfacePointer.getValue(), proxy.getPointer()); + + // Negative check -- this has to fail, the IID should not be + // assigned + hr = proxy.QueryInterface(new REFIID(new IID("{00000000-0000-0000-C000-000000000000}")), interfacePointer); + assertTrue(COMUtils.FAILED(hr)); + } +} diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacks_Test.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacks_Test.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacks_Test.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacks_Test.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,268 +0,0 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM.util; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import com.sun.jna.platform.win32.User32; -import com.sun.jna.platform.win32.WinDef.HWND; -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; -import com.sun.jna.platform.win32.COM.util.annotation.ComProperty; - -public class ComEventCallbacks_Test { - - Factory factory; - - @Before - public void before() { - this.factory = new Factory(); - } - - @After - public void after() { - this.factory.disposeAll(); - this.factory.getComThread().terminate(100); - } - - - @ComObject(progId="Word.Application") - interface ComIMsWordApp extends ComIApplication { - } - - @ComInterface(iid="{00020970-0000-0000-C000-000000000046}") - interface ComIApplication extends IUnknown, IConnectionPoint { - @ComProperty - boolean getVisible(); - - @ComProperty - void setVisible(boolean value); - - @ComMethod - void Quit(boolean SaveChanges, Object OriginalFormat, Boolean RouteDocument); - - @ComProperty - ComIDocuments getDocuments(); - - } - - @ComInterface(iid="{0002096C-0000-0000-C000-000000000046}") - interface ComIDocuments { - @ComMethod - ComIDocument Open(String fileName); - @ComMethod - ComIDocument Add(); - } - - @ComInterface(iid="{0002096B-0000-0000-C000-000000000046}") - interface ComIDocument { - @ComProperty - String getFullName(); - - @ComMethod - void Select(); - } - - @ComInterface(iid="{00020962-0000-0000-C000-000000000046}") - interface ComIWindow {} - - @ComInterface(iid="{00020975-0000-0000-C000-000000000046}") - public interface ComISelection { - @ComProperty - String getText(); - } - - @ComInterface(iid="{00020A01-0000-0000-C000-000000000046}") - interface ApplicationEvents4_Event { - @ComEventCallback(dispid=10) - void WindowActivate(ComIDocument doc, ComIWindow win); - - @ComEventCallback(dispid=2) - void Quit(); - - @ComEventCallback(dispid=12) - void WindowSelectionChange(ComISelection sel); - } - - class ApplicationEvents4_EventListener extends AbstractComEventCallbackListener implements ApplicationEvents4_Event { - - @Override - public void errorReceivingCallbackEvent(String message, Exception exception) { - - } - - Boolean WindowActivate_called = null; - @Override - public void WindowActivate(ComIDocument doc, ComIWindow win) { - if (null!=doc && null !=win) { - String docName = doc.getFullName(); - WindowActivate_called = true; - } - } - - Boolean Quit_called = null; - @Override - public void Quit() { - Quit_called = true; - } - - Boolean WindowSelectionChange_called = null; - @Override - public void WindowSelectionChange(ComISelection sel) { - if (null!=sel) { - String t = sel.getText(); - WindowSelectionChange_called = true; - } - } - - } - - @Test - public void advise_Quit() { - // Create word object - ComIMsWordApp wordObj = factory.createObject(ComIMsWordApp.class); - ComIApplication wordApp = wordObj.queryInterface(ComIApplication.class); - wordApp.setVisible(true); - ApplicationEvents4_EventListener listener = new ApplicationEvents4_EventListener(); - wordApp.advise(ApplicationEvents4_Event.class, listener); - - wordApp.Quit(false, null, null); - - //Wait for event to happen - try { - Thread.sleep(200); - } catch (Exception e) { - e.printStackTrace(); - } - - Assert.assertNotNull(listener.Quit_called); - Assert.assertTrue(listener.Quit_called); - } - - @Test - public void unadvise_Quit() { - // Create word object - ComIMsWordApp wordObj = factory.createObject(ComIMsWordApp.class); - ComIApplication wordApp = wordObj.queryInterface(ComIApplication.class); - - ApplicationEvents4_EventListener listener = new ApplicationEvents4_EventListener(); - IComEventCallbackCookie cookie = wordApp.advise(ApplicationEvents4_Event.class, listener); - - wordApp.unadvise(ApplicationEvents4_Event.class, cookie); - listener.Quit_called=false; - wordApp.Quit(false, null, null); - - //Wait for event to happen - try { - Thread.sleep(200); - } catch (Exception e) { - e.printStackTrace(); - } - - Assert.assertNotNull(listener.Quit_called); - Assert.assertFalse(listener.Quit_called); - } - - @Test - public void WindowActivate() { - // Create word object - ComIMsWordApp wordObj = factory.createObject(ComIMsWordApp.class); - ComIApplication wordApp = wordObj.queryInterface(ComIApplication.class); - wordApp.setVisible(true); - ApplicationEvents4_EventListener listener = new ApplicationEvents4_EventListener(); - wordApp.advise(ApplicationEvents4_Event.class, listener); - wordApp.getDocuments().Add(); - - //bring word doc to front - HWND h = User32.INSTANCE.FindWindow("OpusApp", null); - if (h == null) - h = User32.INSTANCE.FindWindow("NetUIHWND", null); - User32.INSTANCE.ShowWindow(h, User32.SW_RESTORE); - User32.INSTANCE.SetForegroundWindow(h); - - //Wait for event to happen - try { - Thread.sleep(500); - } catch (Exception e) { - e.printStackTrace(); - } - - Assert.assertNotNull(listener.WindowActivate_called); - Assert.assertTrue(listener.WindowActivate_called); - - wordApp.Quit(false, null, null); - - } - - @Test - public void WindowSelectionChanged() { - // Create word object - ComIMsWordApp wordObj = factory.createObject(ComIMsWordApp.class); - ComIApplication wordApp = wordObj.queryInterface(ComIApplication.class); - wordApp.setVisible(true); - ApplicationEvents4_EventListener listener = new ApplicationEvents4_EventListener(); - wordApp.advise(ApplicationEvents4_Event.class, listener); - - ComIDocument doc = wordApp.getDocuments().Add(); - - doc.Select(); - - //Wait for event to happen - try { - Thread.sleep(200); - } catch (Exception e) { - e.printStackTrace(); - } - - Assert.assertNotNull(listener.WindowSelectionChange_called); - Assert.assertTrue(listener.WindowSelectionChange_called); - - wordApp.Quit(false, null, null); - - } - -// @Test -// public void WindowSelectionChanged_jvmCrash() { -// // Create word object -// ComIMsWordApp wordObj = factory.createObject(ComIMsWordApp.class); -// ComIApplication wordApp = wordObj.queryInterface(ComIApplication.class); -// wordApp.setVisible(true); -// ApplicationEvents4_EventListener listener = new ApplicationEvents4_EventListener(); -// wordApp.advise(ApplicationEvents4_Event.class, listener); -// -// -// -// ComIDocument doc = wordApp.getDocuments().Add(); -// -// doc.Select(); -// -// //Wait for event to happen -// try { -// Thread.sleep(2000000); -// } catch (Exception e) { -// e.printStackTrace(); -// } -// -// Assert.assertNotNull(listener.WindowSelectionChange_called); -// Assert.assertTrue(listener.WindowSelectionChange_called); -// -// wordApp.Quit(false, null, null); -// -// } - -} diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ConfigurateLCID_Test.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ConfigurateLCID_Test.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ConfigurateLCID_Test.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ConfigurateLCID_Test.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,69 @@ +package com.sun.jna.platform.win32.COM.util; + +import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; +import com.sun.jna.platform.win32.COM.util.annotation.ComObject; +import com.sun.jna.platform.win32.Ole32; +import com.sun.jna.platform.win32.WinDef.LCID; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + + +public class ConfigurateLCID_Test { + + private Factory factory; + + @Before + public void before() { + Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED); + this.factory = new Factory(); + // switch to english locale (the test is only valid if office is + // installed in a non-english locale + this.factory.setLCID(new LCID(0x0409)); + } + + @After + public void after() { + this.factory.disposeAll(); + Ole32.INSTANCE.CoUninitialize(); + } + + @Test + @Ignore("Only valid for a non-english locale - run manually") + public void testDispatchBaseOnMethodName() throws InterruptedException { + ComExcel_Application excel = factory.createObject(ComExcel_Application.class); + ComIApplication excelApp = excel.queryInterface(ComIApplication.class); + + // Set visiblite of application + excelApp.setProperty("Visible", false); + excelApp.setProperty("DisplayAlerts", false); + + // Get a new workbook. + IDispatch wb = excelApp.getProperty(IDispatch.class, "Workbooks").invokeMethod(IDispatch.class, "Add"); + IDispatch sheet = wb.getProperty(IDispatch.class, "ActiveSheet"); + + sheet.getProperty(IDispatch.class, "Range", "A1").setProperty("Value", 42); + sheet.getProperty(IDispatch.class, "Range", "A2").setProperty("Value", 23); + // Set formula with english command + sheet.getProperty(IDispatch.class, "Range", "A3").setProperty("Formula", "=SUM(A1:A2)"); + + Number result = sheet.getProperty(IDispatch.class, "Range", "A3").getProperty(Number.class, "Value"); + + // The formula should report the sum + Assert.assertEquals(65, result.intValue()); + + excelApp.invokeMethod(Void.class, "Quit"); + } + + @ComObject(progId = "Excel.Application") + public interface ComExcel_Application extends IUnknown { + + } + + @ComInterface(iid = "{000208D5-0000-0000-C000-000000000046}") + public interface ComIApplication extends IUnknown, IConnectionPoint, IDispatch { + } +} diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ConvertTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ConvertTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ConvertTest.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ConvertTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,303 @@ +package com.sun.jna.platform.win32.COM.util; + +import com.sun.jna.Pointer; +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; +import com.sun.jna.platform.win32.COM.util.annotation.ComProperty; +import com.sun.jna.platform.win32.OaIdl.DATE; +import com.sun.jna.platform.win32.OaIdl.VARIANT_BOOL; +import com.sun.jna.platform.win32.Ole32; +import com.sun.jna.platform.win32.Variant; +import com.sun.jna.platform.win32.Variant.VARIANT; +import com.sun.jna.platform.win32.WTypes.BSTR; +import com.sun.jna.platform.win32.WinDef.BOOL; +import com.sun.jna.platform.win32.WinDef.BYTE; +import com.sun.jna.platform.win32.WinDef.CHAR; +import com.sun.jna.platform.win32.WinDef.LONG; +import com.sun.jna.platform.win32.WinDef.SHORT; +import java.util.Date; +import org.junit.AfterClass; +import org.junit.Test; +import static org.junit.Assert.*; +import org.junit.BeforeClass; + +// Untested: IDispatch +// Untested: Proxy +public class ConvertTest { + + private static ObjectFactory fact; + + @BeforeClass + public static void init() { + Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED); + fact = new ObjectFactory(); + } + + @AfterClass + public static void destruct() { + fact.disposeAll(); + fact = null; + Ole32.INSTANCE.CoUninitialize(); + } + + @Test + public void testConvertVariant() { + VARIANT testValue = new Variant.VARIANT(42); + VARIANT resultVariant = Convert.toVariant(testValue); + assertSame(testValue, resultVariant); + assertSame(testValue, Convert.toJavaObject(resultVariant, VARIANT.class, fact, false, false)); + assertSame(42, Convert.toJavaObject(testValue, Object.class, fact, false, false)); + } + + @Test + public void testConvertString() { + // This test leaks the allocated BSTR -- this is tollerated here, as memory usage is minimal + String testString = "Hallo"; + BSTR testValue = new BSTR(testString); + VARIANT resultVariant = Convert.toVariant(testValue); + assertEquals(testString, resultVariant.stringValue()); + assertEquals(testString, Convert.toJavaObject(resultVariant, Object.class, fact, false, false)); + assertEquals(testString, Convert.toJavaObject(resultVariant, String.class, fact, false, false)); + + resultVariant = Convert.toVariant(testString); + assertEquals(testString, resultVariant.stringValue()); + assertEquals(testString, Convert.toJavaObject(resultVariant, Object.class, fact, false, false)); + assertEquals(testString, Convert.toJavaObject(resultVariant, String.class, fact, false, false)); + } + + @Test + public void testConvertBoolean() { + VARIANT_BOOL testVariantBOOL = new VARIANT_BOOL(true); + VARIANT resultVariantBOOL = Convert.toVariant(testVariantBOOL); + assertEquals(true, resultVariantBOOL.booleanValue()); + assertEquals(true, Convert.toJavaObject(resultVariantBOOL, Object.class, fact, false, false)); + assertEquals(true, Convert.toJavaObject(resultVariantBOOL, Boolean.class, fact, false, false)); + assertEquals(true, Convert.toJavaObject(resultVariantBOOL, boolean.class, fact, false, false)); + + BOOL testBOOL = new BOOL(true); + VARIANT resultBOOL = Convert.toVariant(testBOOL); + assertEquals(true, resultBOOL.booleanValue()); + assertEquals(true, Convert.toJavaObject(resultBOOL, Object.class, fact, false, false)); + assertEquals(true, Convert.toJavaObject(resultBOOL, Boolean.class, fact, false, false)); + assertEquals(true, Convert.toJavaObject(resultBOOL, boolean.class, fact, false, false)); + + Boolean testBooleanObj = true; + VARIANT resultBooleanObj = Convert.toVariant(testBooleanObj); + boolean testBoolean = true; + VARIANT resultBoolean = Convert.toVariant(testBoolean); + + assertEquals(true, resultBooleanObj.booleanValue()); + assertEquals(true, resultBoolean.booleanValue()); + assertEquals(true, Convert.toJavaObject(resultBooleanObj, Object.class, fact, false, false)); + assertEquals(true, Convert.toJavaObject(resultBoolean, Object.class, fact, false, false)); + assertEquals(true, Convert.toJavaObject(resultBooleanObj, boolean.class, fact, false, false)); + assertEquals(true, Convert.toJavaObject(resultBoolean, boolean.class, fact, false, false)); + assertEquals(true, Convert.toJavaObject(resultBooleanObj, Boolean.class, fact, false, false)); + assertEquals(true, Convert.toJavaObject(resultBoolean, Boolean.class, fact, false, false)); + } + + @Test + public void testConvertIntTypes() { + LONG testLONG = new LONG(42); + VARIANT resultLONG = Convert.toVariant(testLONG); + assertEquals(42, resultLONG.longValue()); + assertEquals(Integer.class, Convert.toJavaObject(resultLONG, Object.class, fact, false, false).getClass()); + assertEquals(42, Convert.toJavaObject(resultLONG, int.class, fact, false, false)); + assertEquals(42, Convert.toJavaObject(resultLONG, Integer.class, fact, false, false)); + + SHORT testSHORT = new SHORT(42); + VARIANT resultSHORT = Convert.toVariant(testSHORT); + assertEquals(42, resultSHORT.longValue()); + assertEquals(Short.class, Convert.toJavaObject(resultSHORT, Object.class, fact, false, false).getClass()); + assertEquals((short) 42, Convert.toJavaObject(resultSHORT, short.class, fact, false, false)); + assertEquals((short) 42, Convert.toJavaObject(resultSHORT, Short.class, fact, false, false)); + + BYTE testBYTE = new BYTE(42); + VARIANT resultBYTE = Convert.toVariant(testBYTE); + Byte testByteObj = 42; + VARIANT resultByteObj = Convert.toVariant(testByteObj); + byte testByte = 42; + VARIANT resultByte = Convert.toVariant(testByte); + + assertEquals(42, resultBYTE.longValue()); + assertEquals(42, resultByteObj.longValue()); + assertEquals(42, resultByte.longValue()); + assertEquals(Byte.class, Convert.toJavaObject(resultBYTE, Object.class, fact, false, false).getClass()); + assertEquals(Byte.class, Convert.toJavaObject(resultByteObj, Object.class, fact, false, false).getClass()); + assertEquals(Byte.class, Convert.toJavaObject(resultByte, Object.class, fact, false, false).getClass()); + assertEquals((byte) 42, Convert.toJavaObject(resultBYTE, byte.class, fact, false, false)); + assertEquals((byte) 42, Convert.toJavaObject(resultByteObj, byte.class, fact, false, false)); + assertEquals((byte) 42, Convert.toJavaObject(resultByte, byte.class, fact, false, false)); + assertEquals((byte) 42, Convert.toJavaObject(resultBYTE, Byte.class, fact, false, false)); + assertEquals((byte) 42, Convert.toJavaObject(resultByteObj, Byte.class, fact, false, false)); + assertEquals((byte) 42, Convert.toJavaObject(resultByte, Byte.class, fact, false, false)); + + Character testCharObj = 42; + VARIANT resultCharObj = Convert.toVariant(testCharObj); + char testChar = 42; + VARIANT resultChar = Convert.toVariant(testChar); + + assertEquals(42, resultCharObj.longValue()); + assertEquals(42, resultChar.longValue()); + assertEquals(testCharObj, (Character) Convert.toJavaObject(resultCharObj, Object.class, fact, false, false)); + assertEquals(testCharObj, (Character) Convert.toJavaObject(resultChar, Object.class, fact, false, false)); + assertEquals(testCharObj, (Character) Convert.toJavaObject(resultCharObj, char.class, fact, false, false)); + assertEquals(testCharObj, (Character) Convert.toJavaObject(resultChar, char.class, fact, false, false)); + assertEquals(testCharObj, (Character) Convert.toJavaObject(resultCharObj, Character.class, fact, false, false)); + assertEquals(testCharObj, (Character) Convert.toJavaObject(resultChar, Character.class, fact, false, false)); + + CHAR testCHAR = new CHAR(42); + VARIANT resultCHAR = Convert.toVariant(testCHAR); + + assertEquals(42, resultCHAR.longValue()); + assertEquals((byte) 42, Convert.toJavaObject(resultCHAR, Object.class, fact, false, false)); + assertEquals((byte) 42, Convert.toJavaObject(resultCHAR, byte.class, fact, false, false)); + assertEquals((byte) 42, Convert.toJavaObject(resultCHAR, Byte.class, fact, false, false)); + + Short testShortObj = 42; + VARIANT resultShortObj = Convert.toVariant(testShortObj); + short testShort = 42; + VARIANT resultShort = Convert.toVariant(testShort); + + assertEquals(42, resultShortObj.longValue()); + assertEquals(42, resultShort.longValue()); + assertEquals((short) 42, Convert.toJavaObject(resultShortObj, Object.class, fact, false, false)); + assertEquals((short) 42, Convert.toJavaObject(resultShort, Object.class, fact, false, false)); + assertEquals((short) 42, Convert.toJavaObject(resultShortObj, short.class, fact, false, false)); + assertEquals((short) 42, Convert.toJavaObject(resultShort, short.class, fact, false, false)); + assertEquals((short) 42, Convert.toJavaObject(resultShortObj, Short.class, fact, false, false)); + assertEquals((short) 42, Convert.toJavaObject(resultShort, Short.class, fact, false, false)); + + Integer testIntegerObj = 42; + VARIANT resultIntegerObj = Convert.toVariant(testIntegerObj); + int testInteger = 42; + VARIANT resultInteger = Convert.toVariant(testInteger); + + assertEquals(42, resultIntegerObj.longValue()); + assertEquals(42, resultInteger.longValue()); + assertEquals((int) 42, Convert.toJavaObject(resultIntegerObj, Object.class, fact, false, false)); + assertEquals((int) 42, Convert.toJavaObject(resultInteger, Object.class, fact, false, false)); + assertEquals((int) 42, Convert.toJavaObject(resultIntegerObj, int.class, fact, false, false)); + assertEquals((int) 42, Convert.toJavaObject(resultInteger, int.class, fact, false, false)); + assertEquals((int) 42, Convert.toJavaObject(resultIntegerObj, Integer.class, fact, false, false)); + assertEquals((int) 42, Convert.toJavaObject(resultInteger, Integer.class, fact, false, false)); + + Long testLongObj = 42L; + VARIANT resultLongObj = Convert.toVariant(testLongObj); + long testLong = 42; + VARIANT resultLong = Convert.toVariant(testLong); + + assertEquals(42, resultLongObj.longValue()); + assertEquals(42, resultLong.longValue()); + assertEquals((long) 42, Convert.toJavaObject(resultLongObj, Object.class, fact, false, false)); + assertEquals((long) 42, Convert.toJavaObject(resultLong, Object.class, fact, false, false)); + assertEquals((long) 42, Convert.toJavaObject(resultLongObj, long.class, fact, false, false)); + assertEquals((long) 42, Convert.toJavaObject(resultLong, long.class, fact, false, false)); + assertEquals((long) 42, Convert.toJavaObject(resultLongObj, Long.class, fact, false, false)); + assertEquals((long) 42, Convert.toJavaObject(resultLong, Long.class, fact, false, false)); + } + + @Test + public void testConvertFloat() { + Float testFloatObj = 42.23f; + VARIANT resultFloatObj = Convert.toVariant(testFloatObj); + float testFloat = 42.23f; + VARIANT resultFloat = Convert.toVariant(testFloat); + + assertEquals(42.23f, resultFloatObj.floatValue(), 0.01); + assertEquals(42.23f, resultFloat.floatValue(), 0.01); + assertEquals(42.23d, resultFloat.doubleValue(), 0.01); + assertEquals(42.23f, (Float) Convert.toJavaObject(resultFloatObj, Object.class, fact, false, false), 0.01); + assertEquals(42.23f, (Float) Convert.toJavaObject(resultFloat, Object.class, fact, false, false), 0.01); + assertEquals(42.23f, (Float) Convert.toJavaObject(resultFloatObj, float.class, fact, false, false), 0.01); + assertEquals(42.23f, (Float) Convert.toJavaObject(resultFloat, float.class, fact, false, false), 0.01); + assertEquals(42.23f, (Float) Convert.toJavaObject(resultFloatObj, Float.class, fact, false, false), 0.01); + assertEquals(42.23f, (Float) Convert.toJavaObject(resultFloat, Float.class, fact, false, false), 0.01); + assertEquals(42.23d, (Double) Convert.toJavaObject(resultFloat, double.class, fact, false, false), 0.01); + + Double testDoubleObj = 42.23; + VARIANT resultDoubleObj = Convert.toVariant(testDoubleObj); + double testDouble = 42.23; + VARIANT resultDouble = Convert.toVariant(testDouble); + + assertEquals(42.23, resultDoubleObj.doubleValue(), 0.01); + assertEquals(42.23, resultDouble.doubleValue(), 0.01); + assertEquals(42.23f, resultDouble.floatValue(), 0.01); + assertEquals(42.23, (Double) Convert.toJavaObject(resultDoubleObj, Object.class, fact, false, false), 0.01); + assertEquals(42.23, (Double) Convert.toJavaObject(resultDouble, Object.class, fact, false, false), 0.01); + assertEquals(42.23, (Double) Convert.toJavaObject(resultDoubleObj, double.class, fact, false, false), 0.01); + assertEquals(42.23, (Double) Convert.toJavaObject(resultDouble, double.class, fact, false, false), 0.01); + assertEquals(42.23, (Double) Convert.toJavaObject(resultDoubleObj, Double.class, fact, false, false), 0.01); + assertEquals(42.23, (Double) Convert.toJavaObject(resultDouble, Double.class, fact, false, false), 0.01); + assertEquals(42.23f, (Float) Convert.toJavaObject(resultDouble, float.class, fact, false, false), 0.01); + } + + @Test + public void testConvertDate() { + Date testDate = new Date(2015 - 1900, 1, 1, 9, 0, 0); + VARIANT resultDate = Convert.toVariant(testDate); + DATE testDATE = new DATE(testDate); + VARIANT resultDATE = Convert.toVariant(testDATE); + + assertEquals(testDate, resultDate.dateValue()); + assertEquals(testDate, resultDATE.dateValue()); + assertEquals(testDate, Convert.toJavaObject(resultDate, Object.class, fact, false, false)); + assertEquals(testDate, Convert.toJavaObject(resultDATE, Object.class, fact, false, false)); + assertEquals(testDate, Convert.toJavaObject(resultDate, Date.class, fact, false, false)); + assertEquals(testDate, Convert.toJavaObject(resultDATE, Date.class, fact, false, false)); + } + + @Test + public void testConvertEnum() { + TestEnum testEnum = TestEnum.Val2; + VARIANT resultEnum = Convert.toVariant(testEnum); + assertEquals((int) testEnum.getValue(), resultEnum.intValue()); + assertEquals((int) testEnum.getValue(), Convert.toJavaObject(resultEnum, Object.class, fact, false, false)); + assertEquals(testEnum, Convert.toJavaObject(resultEnum, TestEnum.class, fact, false, false)); + } + + @Test + public void testReturnPrimitiveVoid() { + FileSystemObject app = fact.createObject(FileSystemObject.class); + // It is assumed that "C" is the holy drive letter, that will + // always be present + assertTrue(app.DriveExistsPrimitive("C:")); + assertTrue(app.DriveExistsObject("C:")); + app.DriveExistsVoid("C:"); + } +} + +@ComObject(clsId = "{0D43FE01-F093-11CF-8940-00A0C9054228}") +interface FileSystemObject extends IFileSystem3 { +} + +@ComInterface(iid = "{2A0B9D10-4B87-11D3-A97A-00104B365C9F}") +interface IFileSystem3 extends IUnknown, IConnectionPoint { + + @ComMethod(dispId = 0x0000271f) + boolean DriveExistsPrimitive(String driveName); + + @ComMethod(dispId = 0x0000271f) + Boolean DriveExistsObject(String driveName); + + @ComMethod(dispId = 0x0000271f) + void DriveExistsVoid(String driveName); +} + +enum TestEnum implements IComEnum { + Val1(1), + Val2(2), + Val3(3),; + + long value; + + private TestEnum(long val) { + this.value = val; + } + + public long getValue() { + return this.value; + } + +} diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/util/HybdridCOMInvocationTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/util/HybdridCOMInvocationTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/util/HybdridCOMInvocationTest.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/util/HybdridCOMInvocationTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,172 @@ +package com.sun.jna.platform.win32.COM.util; + +import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.COM.COMException; +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.util.annotation.ComInterface; +import com.sun.jna.platform.win32.COM.util.annotation.ComMethod; +import com.sun.jna.platform.win32.COM.util.annotation.ComObject; +import com.sun.jna.platform.win32.Guid; +import com.sun.jna.platform.win32.Guid.CLSID; +import com.sun.jna.platform.win32.Guid.GUID; +import com.sun.jna.platform.win32.Guid.IID; +import com.sun.jna.platform.win32.Guid.REFIID; +import com.sun.jna.platform.win32.Kernel32; +import com.sun.jna.platform.win32.OaIdl; +import com.sun.jna.platform.win32.OaIdl.DISPID; +import com.sun.jna.platform.win32.Ole32; +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; +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; +import com.sun.jna.ptr.PointerByReference; +import java.util.logging.Level; +import java.util.logging.Logger; +import static org.hamcrest.CoreMatchers.is; +import org.junit.After; +import org.junit.Test; +import static org.junit.Assert.*; +import org.junit.Before; + +/** + * In the word COM bindings it was determined, that some methods can't be called + * with only wFlags OleAuto.DISPATCH_METHOD or OleAuto.DISPATCH_PROPERTYGET. + * + * For these methods both flags need to be set. + * + * https://www.delphitools.info/2013/04/30/gaining-visual-basic-ole-super-powers/ + * https://msdn.microsoft.com/en-us/library/windows/desktop/ms221486(v=vs.85).aspx + * + * A sample function is InchesToPoints from thw word typelibrary + */ +public class HybdridCOMInvocationTest { + + static { + ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true); + } + + private static final Logger LOG = Logger.getLogger(HybdridCOMInvocationTest.class.getName()); + + private static final String CLSID_WORD_STRING = "{000209FF-0000-0000-C000-000000000046}"; + private static final String IID_APPLICATION_STRING = "{00020970-0000-0000-C000-000000000046}"; + private static final GUID CLSID_WORD = new GUID(CLSID_WORD_STRING); + private static final IID IID_APPLICATION = new IID(new GUID(IID_APPLICATION_STRING)); + + @After + public void tearDown() throws Exception { + Ole32.INSTANCE.CoUninitialize(); + } + + @Before + public void setUp() throws Exception { + // Initialize COM for this thread... + Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED); + } + + @Test + public void testOfficeInvocationProblemCOMUtil() { + ObjectFactory fact = new ObjectFactory(); + Application app; + try { + app = fact.createObject(Application.class); + } catch (COMException ex) { + LOG.log(Level.INFO, "HybdridCOMInvocationTest test was not run, MS Word object could not be instantiated.", ex); + return; + } + // If this fails: remember: floats are not exact, if this happens replace + // with a range check + assertThat(app.InchesToPoints(1F), is(72.0f)); + fact.disposeAll(); + } + + @Test + public void testOfficeInvocationProblemCOMBindingObject() { + WordApplication app; + try { + app = new WordApplication(false); + } catch (COMException ex) { + LOG.log(Level.INFO, "HybdridCOMInvocationTest test was not run, MS Word object could not be instantiated.", ex); + return; + } + assertThat(app.InchesToPoints(1F), is(72.0f)); + } + + + public void testOfficeInvocationDemonstration() { + // THIS IS NOT A TEST + // + // This reproduces the problem by using the dispatch directly. + + PointerByReference pDispatch = new PointerByReference(); + + HRESULT hr = Ole32.INSTANCE.CoCreateInstance(CLSID_WORD, null, + WTypes.CLSCTX_SERVER, IID_APPLICATION, pDispatch); + + if(! COMUtils.SUCCEEDED(hr)) { + LOG.log(Level.INFO, "HybdridCOMInvocationTest test was not run, MS Word object could not be instantiated."); + return; + } + + Dispatch dp = new Dispatch(pDispatch.getValue()); + + // DispID of InchesToPoints + DISPID dispId = new OaIdl.DISPID(0x00000172); + // Interface _Application of MS Word type library + WinDef.LCID LOCALE_SYSTEM_DEFAULT = Kernel32.INSTANCE.GetSystemDefaultLCID(); + Variant.VARIANT.ByReference result = new Variant.VARIANT.ByReference(); + OaIdl.EXCEPINFO.ByReference pExcepInfo = new OaIdl.EXCEPINFO.ByReference(); + IntByReference puArgErr = new IntByReference(); + + WORD wFlagsMethod = new WinDef.WORD(OleAuto.DISPATCH_METHOD); + WORD wFlagsGet = new WinDef.WORD(OleAuto.DISPATCH_PROPERTYGET); + WORD wFlagsCombined = new WinDef.WORD(OleAuto.DISPATCH_METHOD | OleAuto.DISPATCH_PROPERTYGET); + + OleAuto.DISPPARAMS.ByReference pDispParams = new OleAuto.DISPPARAMS.ByReference(); + VARIANT[] params = new VARIANT[] {new VARIANT(1f)}; + pDispParams.setArgs(params); + + // Call InchesToPoints as a method + hr = dp.Invoke(dispId, new REFIID(Guid.IID_NULL), LOCALE_SYSTEM_DEFAULT, wFlagsMethod, pDispParams, result, pExcepInfo, puArgErr); + assertTrue(COMUtils.FAILED(hr)); + + // Call InchesToPoints as a property getter + hr = dp.Invoke(dispId, new REFIID(Guid.IID_NULL), LOCALE_SYSTEM_DEFAULT, wFlagsGet, pDispParams, result, pExcepInfo, puArgErr); + assertTrue(COMUtils.FAILED(hr)); + + // Call InchesToPoints as a hybrid + 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()); + } + + @ComObject(clsId = CLSID_WORD_STRING) + public static interface Application extends IDispatch, _Application { + } + + @ComInterface(iid = IID_APPLICATION_STRING) + public static interface _Application { + @ComMethod + Float InchesToPoints(Float value); + } + + public static class WordApplication extends COMLateBindingObject { + + public WordApplication(boolean useActiveInstance) { + super(new CLSID(CLSID_WORD), 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)}); + return pvResult.floatValue(); + } + } +} diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/util/IDispatchTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/util/IDispatchTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/util/IDispatchTest.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/util/IDispatchTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,429 @@ +package com.sun.jna.platform.win32.COM.util; + +import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.AbstractWin32TestSupport; +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; +import com.sun.jna.platform.win32.COM.util.annotation.ComProperty; +import com.sun.jna.platform.win32.OaIdl.DISPID; +import com.sun.jna.platform.win32.Ole32; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.*; + +public class IDispatchTest { + + ObjectFactory factory; + + @Before + public void before() { + AbstractWin32TestSupport.killProcessByName("iexplore.exe"); + try { + Thread.sleep(5 * 1000); + } catch (InterruptedException ex) {} + Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED); + this.factory = new ObjectFactory(); + } + + @After + public void after() { + this.factory.disposeAll(); + Ole32.INSTANCE.CoUninitialize(); + } + + @Test + public void testDispatchBaseOnMethodName() throws InterruptedException { + ComInternetExplorerMethodname ieApp = factory.createObject(ComInternetExplorerMethodname.class); + + // Test getting property + assertFalse(ieApp.getVisible()); + + // Test setting property + ieApp.setVisible(Boolean.TRUE); + assertTrue(ieApp.getVisible()); + + // Check navigate function and with that the method invocation + assertTrue(ieApp.getLocationURL().isEmpty()); + + ieApp.Navigate2("https://github.com/java-native-access/"); + + // Check max. 2s if Navigation happend + boolean navigationHappend = false; + for (int i = 0; i < 10; i++) { + String url = ieApp.getLocationURL(); + if (!url.isEmpty()) { + navigationHappend = true; + break; + } else { + Thread.sleep(200); + } + } + + ieApp.Quit(); + + assertTrue(navigationHappend); + } + + @ComObject(progId = "Internet.Explorer.1", clsId = "{0002DF01-0000-0000-C000-000000000046}") + interface ComInternetExplorerMethodname { + @ComProperty + String getLocationURL(); + + @ComMethod + void Navigate2(String url); + + @ComProperty + Boolean getVisible(); + + @ComProperty + void setVisible(Boolean visible); + + @ComMethod + void Quit(); + } + + @Test + public void testDispatchBaseOnNamed() throws InterruptedException { + ComInternetExplorerNamed ieApp = factory.createObject(ComInternetExplorerNamed.class); + + // Test getting property + assertFalse(ieApp.getVisible_MOD()); + + // Test setting property + ieApp.setVisible_MOD(Boolean.TRUE); + assertTrue(ieApp.getVisible_MOD()); + + // Check navigate function and with that the method invocation + assertTrue(ieApp.getLocationURL_MOD().isEmpty()); + + ieApp.Navigate2_MOD("https://github.com/java-native-access/"); + + // Check max. 10s if Navigation happend + boolean navigationHappend = false; + for (int i = 0; i < 50; i++) { + String url = ieApp.getLocationURL_MOD(); + if (!url.isEmpty()) { + navigationHappend = true; + break; + } else { + Thread.sleep(200); + } + } + + ieApp.Quit_MOD(); + + assertTrue(navigationHappend); + } + + @ComObject(progId = "Internet.Explorer.1", clsId = "{0002DF01-0000-0000-C000-000000000046}") + interface ComInternetExplorerNamed { + @ComProperty(name="LocationURL") + String getLocationURL_MOD(); + + @ComMethod(name="Navigate2") + void Navigate2_MOD(String url); + + @ComProperty(name="Visible") + Boolean getVisible_MOD(); + + @ComProperty(name="Visible") + void setVisible_MOD(Boolean visible); + + @ComMethod(name="Quit") + void Quit_MOD(); + } + + @Test + public void testDispatchBaseOnDISPID() throws InterruptedException { + ComInternetExplorerDISPID ieApp = factory.createObject(ComInternetExplorerDISPID.class); + + // Test getting property + assertFalse(ieApp.getVisible_MOD()); + + // Test setting property + ieApp.setVisible_MOD(Boolean.TRUE); + assertTrue(ieApp.getVisible_MOD()); + + // Check navigate function and with that the method invocation + assertTrue(ieApp.getLocationURL_MOD().isEmpty()); + + ieApp.Navigate2_MOD("https://github.com/java-native-access/"); + + // Check max. 2s if Navigation happend + boolean navigationHappend = false; + for (int i = 0; i < 50; i++) { + String url = ieApp.getLocationURL_MOD(); + if (!url.isEmpty()) { + navigationHappend = true; + break; + } else { + Thread.sleep(200); + } + } + + ieApp.Quit_MOD(); + + assertTrue(navigationHappend); + } + + @ComObject(progId = "Internet.Explorer.1", clsId = "{0002DF01-0000-0000-C000-000000000046}") + interface ComInternetExplorerDISPID { + @ComProperty(dispId = 0x000000d3) + String getLocationURL_MOD(); + + @ComMethod(dispId = 0x000001f4) + void Navigate2_MOD(String url); + + @ComProperty(dispId = 0x00000192) + Boolean getVisible_MOD(); + + @ComProperty(dispId = 0x00000192) + void setVisible_MOD(Boolean visible); + + @ComMethod(dispId = 0x0000012c) + void Quit_MOD(); + } + + @Test + public void testIDispatchName() throws InterruptedException { + ComInternetExplorerIDispatch ieApp = factory.createObject(ComInternetExplorerIDispatch.class); + + // Test getting property + assertFalse(ieApp.getProperty(Boolean.class, "Visible")); + + // Test setting property + ieApp.setProperty("Visible", Boolean.TRUE); + assertTrue(ieApp.getProperty(Boolean.class, "Visible")); + + // Check navigate function and with that the method invocation + assertTrue(ieApp.getProperty(String.class, "LocationURL").isEmpty()); + + ieApp.invokeMethod(Void.class, "Navigate2", "https://github.com/java-native-access/"); + + // Check max. 10s if Navigation happend + boolean navigationHappend = false; + for (int i = 0; i < 50; i++) { + String url = ieApp.getProperty(String.class, "LocationURL"); + if (!url.isEmpty()) { + navigationHappend = true; + break; + } else { + Thread.sleep(200); + } + } + + ieApp.invokeMethod(Void.class, "Quit"); + + assertTrue(navigationHappend); + } + + @Test + public void testIDispatchDISPID() throws InterruptedException { + DISPID locationURL = new DISPID(0x000000d3); + DISPID visible = new DISPID(0x00000192); + DISPID quit = new DISPID(0x0000012c); + DISPID navigate2 = new DISPID(0x000001f4); + + ComInternetExplorerIDispatch ieApp = factory.createObject(ComInternetExplorerIDispatch.class); + + // Test getting property + assertFalse(ieApp.getProperty(Boolean.class, visible)); + + // Test setting property + ieApp.setProperty(visible, Boolean.TRUE); + assertTrue(ieApp.getProperty(Boolean.class, visible)); + + // Check navigate function and with that the method invocation + assertTrue(ieApp.getProperty(String.class, locationURL).isEmpty()); + + ieApp.invokeMethod(Void.class, navigate2, "https://github.com/java-native-access/"); + + // Check max. 10s if Navigation happend + boolean navigationHappend = false; + for (int i = 0; i < 50; i++) { + String url = ieApp.getProperty(String.class, locationURL); + if (!url.isEmpty()) { + navigationHappend = true; + break; + } else { + Thread.sleep(200); + } + } + + ieApp.invokeMethod(Void.class, quit); + + assertTrue(navigationHappend); + } + + @ComObject(progId = "Internet.Explorer.1", clsId = "{0002DF01-0000-0000-C000-000000000046}") + interface ComInternetExplorerIDispatch extends IDispatch { + } + + @Test + public void testCallbackAll() throws InterruptedException { + ComInternetExplorerEventTest ieApp = factory.createObject(ComInternetExplorerEventTest.class); + ieApp.setVisible(false); + + DWebBrowserEvents2_Listener listener1 = new DWebBrowserEvents2_Listener(); + DWebBrowserEvents2_Listener listener2 = new DWebBrowserEvents2_Listener(); + DWebBrowserEvents2_Listener listener3 = new DWebBrowserEvents2_Listener(); + DWebBrowserEvents2_Listener listener4 = new DWebBrowserEvents2_Listener(); + DWebBrowserEvents2_Listener listener5 = new DWebBrowserEvents2_Listener(); + + IComEventCallbackCookie cookie1 = ieApp.advise(DWebBrowserEvents2EventTestIDispatch.class, listener1); + IComEventCallbackCookie cookie2 = ieApp.advise(DWebBrowserEvents2EventTestIUnknown.class, listener2); + IComEventCallbackCookie cookie3 = ieApp.advise(DWebBrowserEvents2EventTestUtilIDispatch.class, listener3); + IComEventCallbackCookie cookie4 = ieApp.advise(DWebBrowserEvents2EventTestUtilIUnknown.class, listener4); + IComEventCallbackCookie cookie5 = ieApp.advise(DWebBrowserEvents2EventTestSubclass.class, listener5); + + ieApp.Navigate2("https://github.com/"); + + for(int i = 0; i < 50; i++) { + Thread.sleep(200); + if(listener1.IDispatch && listener2.IUnknown && listener3.UtilIDispatch && listener4.UtilIUnknown && listener5.Subclass) { + break; + } + } + + ieApp.unadvise(DWebBrowserEvents2EventTestIDispatch.class, cookie1); + ieApp.unadvise(DWebBrowserEvents2EventTestIUnknown.class, cookie2); + ieApp.unadvise(DWebBrowserEvents2EventTestUtilIDispatch.class, cookie3); + ieApp.unadvise(DWebBrowserEvents2EventTestUtilIUnknown.class, cookie4); + ieApp.unadvise(DWebBrowserEvents2EventTestSubclass.class, cookie5); + + ieApp.Quit(); + + assertTrue(listener1.IDispatch); + assertFalse(listener1.IUnknown); + assertFalse(listener1.UtilIDispatch); + assertFalse(listener1.UtilIUnknown); + assertFalse(listener1.Subclass); + + assertFalse(listener2.IDispatch); + assertTrue(listener2.IUnknown); + assertFalse(listener2.UtilIDispatch); + assertFalse(listener2.UtilIUnknown); + assertFalse(listener2.Subclass); + + assertFalse(listener3.IDispatch); + assertFalse(listener3.IUnknown); + assertTrue(listener3.UtilIDispatch); + assertFalse(listener3.UtilIUnknown); + assertFalse(listener3.Subclass); + + assertFalse(listener4.IDispatch); + assertFalse(listener4.IUnknown); + assertFalse(listener4.UtilIDispatch); + assertTrue(listener4.UtilIUnknown); + assertFalse(listener4.Subclass); + + assertFalse(listener5.IDispatch); + assertFalse(listener5.IUnknown); + assertFalse(listener5.UtilIDispatch); + assertFalse(listener5.UtilIUnknown); + assertTrue(listener5.Subclass); + } + + @ComObject(progId = "Internet.Explorer.1", clsId = "{0002DF01-0000-0000-C000-000000000046}") + interface ComInternetExplorerEventTest extends ComIWebBrowser2EventTest { + } + + @ComInterface(iid = "{D30C1661-CDAF-11D0-8A3E-00C04FC9E26E}") + interface ComIWebBrowser2EventTest extends IUnknown, IConnectionPoint { + + @ComProperty + boolean getVisible(); + + @ComProperty + void setVisible(boolean value); + + @ComMethod + void Quit(); + + @ComMethod + void Navigate2(String url); + } + + @ComInterface(iid = "{34A715A0-6587-11D0-924A-0020AFC7AC4D}") + interface DWebBrowserEvents2EventTestUtilIUnknown { + + @ComEventCallback(dispid = 0x000000fc) + void NavigateComplete2UtilIUnknown(IUnknown source, Object url); + } + + @ComInterface(iid = "{34A715A0-6587-11D0-924A-0020AFC7AC4D}") + interface DWebBrowserEvents2EventTestUtilIDispatch { + + @ComEventCallback(dispid = 0x000000fc) + void NavigateComplete2UtilIDispatch(IDispatch source, Object url); + } + + @ComInterface(iid = "{34A715A0-6587-11D0-924A-0020AFC7AC4D}") + interface DWebBrowserEvents2EventTestIUnknown { + + @ComEventCallback(dispid = 0x000000fc) + void NavigateComplete2IUnknown(com.sun.jna.platform.win32.COM.IUnknown source, Object url); + } + + @ComInterface(iid = "{34A715A0-6587-11D0-924A-0020AFC7AC4D}") + interface DWebBrowserEvents2EventTestIDispatch { + + @ComEventCallback(dispid = 0x000000fc) + void NavigateComplete2IDispatch(com.sun.jna.platform.win32.COM.IDispatch source, Object url); + } + + @ComInterface(iid = "{34A715A0-6587-11D0-924A-0020AFC7AC4D}") + interface DWebBrowserEvents2EventTestSubclass { + + @ComEventCallback(dispid = 0x000000fc) + void NavigateComplete2Subclass(ComIWebBrowser2EventTest source, Object url); + } + + class DWebBrowserEvents2_Listener extends AbstractComEventCallbackListener implements DWebBrowserEvents2EventTestUtilIUnknown, DWebBrowserEvents2EventTestUtilIDispatch, DWebBrowserEvents2EventTestIUnknown, DWebBrowserEvents2EventTestIDispatch, DWebBrowserEvents2EventTestSubclass { + + volatile boolean UtilIUnknown = false; + volatile boolean UtilIDispatch = false; + volatile boolean IUnknown = false; + volatile boolean IDispatch = false; + volatile boolean Subclass = false; + + @Override + public void errorReceivingCallbackEvent(String message, Exception exception) { +// System.err.println(message); + } + + public void NavigateComplete2UtilIUnknown(IUnknown source, Object url) { + if (url instanceof String && ((String) url).startsWith("https://github.com/")) { + UtilIUnknown = true; + } + } + + public void NavigateComplete2UtilIDispatch(IDispatch source, Object url) { + if (url instanceof String && ((String) url).startsWith("https://github.com/")) { + UtilIDispatch = true; + } + } + + public void NavigateComplete2IUnknown(com.sun.jna.platform.win32.COM.IUnknown source, Object url) { + if (url instanceof String && ((String) url).startsWith("https://github.com/")) { + IUnknown = true; + } + } + + public void NavigateComplete2IDispatch(com.sun.jna.platform.win32.COM.IDispatch source, Object url) { + if (url instanceof String && ((String) url).startsWith("https://github.com/")) { + IDispatch = true; + } + } + + public void NavigateComplete2Subclass(ComIWebBrowser2EventTest source, Object url) { + if (url instanceof String && ((String) url).startsWith("https://github.com/")) { + Subclass = true; + } + } + } +} diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ProxyObjectFactory_Test.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ProxyObjectFactory_Test.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ProxyObjectFactory_Test.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ProxyObjectFactory_Test.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,188 @@ +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ +package com.sun.jna.platform.win32.COM.util; + +import com.sun.jna.Pointer; +import static org.junit.Assert.*; + +import java.io.File; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; +import com.sun.jna.platform.win32.COM.util.annotation.ComObject; +import com.sun.jna.platform.win32.COM.util.annotation.ComMethod; +import com.sun.jna.platform.win32.COM.util.annotation.ComProperty; +import com.sun.jna.platform.win32.Ole32; + +public class ProxyObjectFactory_Test { + + static { + ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true); + } + + @ComInterface(iid="{00020970-0000-0000-C000-000000000046}") + interface Application extends IUnknown { + @ComProperty + boolean getVisible(); + + @ComProperty + void setVisible(boolean value); + + @ComMethod + void Quit(boolean SaveChanges, Object OriginalFormat, Boolean RouteDocument); + + @ComMethod + public void Quit(Object... someArgs); + + @ComMethod(dispId = 0x00000183) + public float PointsToPixels(float points, Object... someArgs); + + @ComProperty(dispId = 0x00000006) + public Documents getDocuments(); + } + + @ComInterface(iid = "{0002096C-0000-0000-C000-000000000046}") + public interface Documents extends IDispatch { + @ComMethod + public _Document Add(Object template, Object newTemplate, Object documentType, Object visible); + + @ComMethod + public _Document Add(Object... someArgs); + } + + @ComInterface(iid = "{0002096B-0000-0000-C000-000000000046}") + public interface _Document extends IDispatch { + @ComMethod + public void SaveAs(Object fileName, Object fileFormat, Object lockComments, Object password, + Object addToRecentFiles, Object writePassword, Object readOnlyRecommended, Object embedTrueTypeFonts, + Object saveNativePictureFormat, Object saveFormsData, Object saveAsAOCELetter, Object encoding, + Object insertLineBreaks, Object allowSubstitutions, Object lineEnding, Object addBiDiMarks); + + @ComMethod + public void SaveAs(Object... someArgs); + } + + public enum WdSaveFormat implements IComEnum { + wdFormatDocument(0), wdFormatText(2), wdFormatRTF(6), wdFormatHTML(8), wdFormatPDF(17); + + private long _value; + + private WdSaveFormat(long value) { + _value = value; + } + + @Override + public long getValue() { + return _value; + } + } + + @ComObject(progId="Word.Application") + interface MsWordApp extends Application { + } + + Factory factory; + + @Before + public void before() { + this.factory = new Factory(); + //ensure there are no word applications running. + while(true) { + try { + MsWordApp ao = this.factory.fetchObject(MsWordApp.class); + Application a = ao.queryInterface(Application.class); + try { + a.Quit(true, null, null); + try { + //wait for it to quit + Thread.sleep(100); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } catch (Exception e) { + e.printStackTrace();e.getCause().printStackTrace(); + } + } catch(Exception e) { + break; + } + } + } + + @After + public void after() { + factory.disposeAll(); + factory.getComThread().terminate(10000); + } + + + @Test + public void equals() { + MsWordApp comObj1 = this.factory.createObject(MsWordApp.class); + MsWordApp comObj2 = this.factory.fetchObject(MsWordApp.class); + + boolean res = comObj1.equals(comObj2); + + assertTrue(res); + + comObj1.Quit(false, null,null); + } + + @Test + public void notEquals() { + MsWordApp comObj1 = this.factory.createObject(MsWordApp.class); + MsWordApp comObj2 = this.factory.createObject(MsWordApp.class); + + boolean res = comObj1.equals(comObj2); + + assertFalse(res); + + comObj1.Quit(false, null,null); + } + + @Test + public void accessWhilstDisposing() { + MsWordApp comObj1 = this.factory.createObject(MsWordApp.class); + + //TODO: how to test this? + + this.factory.disposeAll(); + + } + + @Test + public void testVarargsCallWithoutVarargParameter() { + MsWordApp comObj = this.factory.createObject(MsWordApp.class); + + // call must work without exception: + float f = comObj.PointsToPixels(25.3f); + comObj.Quit(); + } + + @Test + public void testVarargsCallWithParameter() { + MsWordApp comObj = this.factory.createObject(MsWordApp.class); + + Documents documents = comObj.getDocuments(); + _Document myDocument = documents.Add(); + + String path = new File(".").getAbsolutePath(); + myDocument.SaveAs(path + "\\abcdefg", WdSaveFormat.wdFormatPDF); + comObj.Quit(); + + boolean wasDeleted = new File("abcdefg.pdf").delete(); + assertTrue(wasDeleted); + } +} diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ProxyObjectObjectFactory_Test.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ProxyObjectObjectFactory_Test.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ProxyObjectObjectFactory_Test.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ProxyObjectObjectFactory_Test.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,189 @@ +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ +package com.sun.jna.platform.win32.COM.util; + +import com.sun.jna.Pointer; +import static org.junit.Assert.*; + +import java.io.File; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; +import com.sun.jna.platform.win32.COM.util.annotation.ComObject; +import com.sun.jna.platform.win32.COM.util.annotation.ComMethod; +import com.sun.jna.platform.win32.COM.util.annotation.ComProperty; +import com.sun.jna.platform.win32.Ole32; + +public class ProxyObjectObjectFactory_Test { + + static { + ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true); + } + + @ComInterface(iid="{00020970-0000-0000-C000-000000000046}") + interface Application extends IUnknown { + @ComProperty + boolean getVisible(); + + @ComProperty + void setVisible(boolean value); + + @ComMethod + void Quit(boolean SaveChanges, Object OriginalFormat, Boolean RouteDocument); + + @ComMethod + public void Quit(Object... someArgs); + + @ComMethod(dispId = 0x00000183) + public float PointsToPixels(float points, Object... someArgs); + + @ComProperty(dispId = 0x00000006) + public Documents getDocuments(); + } + + @ComInterface(iid = "{0002096C-0000-0000-C000-000000000046}") + public interface Documents extends IDispatch { + @ComMethod + public _Document Add(Object template, Object newTemplate, Object documentType, Object visible); + + @ComMethod + public _Document Add(Object... someArgs); + } + + @ComInterface(iid = "{0002096B-0000-0000-C000-000000000046}") + public interface _Document extends IDispatch { + @ComMethod + public void SaveAs(Object fileName, Object fileFormat, Object lockComments, Object password, + Object addToRecentFiles, Object writePassword, Object readOnlyRecommended, Object embedTrueTypeFonts, + Object saveNativePictureFormat, Object saveFormsData, Object saveAsAOCELetter, Object encoding, + Object insertLineBreaks, Object allowSubstitutions, Object lineEnding, Object addBiDiMarks); + + @ComMethod + public void SaveAs(Object... someArgs); + } + + public enum WdSaveFormat implements IComEnum { + wdFormatDocument(0), wdFormatText(2), wdFormatRTF(6), wdFormatHTML(8), wdFormatPDF(17); + + private long _value; + + private WdSaveFormat(long value) { + _value = value; + } + + @Override + public long getValue() { + return _value; + } + } + + @ComObject(progId="Word.Application") + interface MsWordApp extends Application { + } + + ObjectFactory factory; + + @Before + public void before() { + Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED); + this.factory = new ObjectFactory(); + //ensure there are no word applications running. + while(true) { + try { + MsWordApp ao = this.factory.fetchObject(MsWordApp.class); + Application a = ao.queryInterface(Application.class); + try { + a.Quit(true, null, null); + try { + //wait for it to quit + Thread.sleep(100); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } catch (Exception e) { + e.printStackTrace();e.getCause().printStackTrace(); + } + } catch(Exception e) { + break; + } + } + } + + @After + public void after() { + factory.disposeAll(); + Ole32.INSTANCE.CoUninitialize(); + } + + + @Test + public void equals() { + MsWordApp comObj1 = this.factory.createObject(MsWordApp.class); + MsWordApp comObj2 = this.factory.fetchObject(MsWordApp.class); + + boolean res = comObj1.equals(comObj2); + + assertTrue(res); + + comObj1.Quit(false, null,null); + } + + @Test + public void notEquals() { + MsWordApp comObj1 = this.factory.createObject(MsWordApp.class); + MsWordApp comObj2 = this.factory.createObject(MsWordApp.class); + + boolean res = comObj1.equals(comObj2); + + assertFalse(res); + + comObj1.Quit(false, null,null); + } + + @Test + public void accessWhilstDisposing() { + MsWordApp comObj1 = this.factory.createObject(MsWordApp.class); + + //TODO: how to test this? + + this.factory.disposeAll(); + + } + + @Test + public void testVarargsCallWithoutVarargParameter() { + MsWordApp comObj = this.factory.createObject(MsWordApp.class); + + // call must work without exception: + float f = comObj.PointsToPixels(25.3f); + comObj.Quit(); + } + + @Test + public void testVarargsCallWithParameter() { + MsWordApp comObj = this.factory.createObject(MsWordApp.class); + + Documents documents = comObj.getDocuments(); + _Document myDocument = documents.Add(); + + String path = new File(".").getAbsolutePath(); + myDocument.SaveAs(path + "\\abcdefg", WdSaveFormat.wdFormatPDF); + comObj.Quit(); + + boolean wasDeleted = new File("abcdefg.pdf").delete(); + assertTrue(wasDeleted); + } +} diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ProxyObject_Test.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ProxyObject_Test.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ProxyObject_Test.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ProxyObject_Test.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,130 +0,0 @@ -/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32.COM.util; - -import static org.junit.Assert.*; - -import java.util.List; - -import javax.management.InvalidApplicationException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.sun.jna.platform.win32.COM.COMException; -import com.sun.jna.platform.win32.COM.COMUtils; -import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; -import com.sun.jna.platform.win32.COM.util.annotation.ComObject; -import com.sun.jna.platform.win32.COM.util.annotation.ComMethod; -import com.sun.jna.platform.win32.COM.util.annotation.ComProperty; -import com.sun.jna.platform.win32.Guid.IID; -import com.sun.jna.platform.win32.Ole32; -import com.sun.jna.platform.win32.Ole32Util; -import com.sun.jna.platform.win32.OleAuto; -import com.sun.jna.platform.win32.Variant; -import com.sun.jna.platform.win32.WinDef; -import com.sun.jna.platform.win32.WinNT; -import com.sun.jna.ptr.PointerByReference; - -public class ProxyObject_Test { - - @ComInterface(iid="{00020970-0000-0000-C000-000000000046}") - interface Application extends IUnknown { - @ComProperty - boolean getVisible(); - - @ComProperty - void setVisible(boolean value); - - @ComMethod - void Quit(boolean SaveChanges, Object OriginalFormat, Boolean RouteDocument); - } - - @ComObject(progId="Word.Application") - interface MsWordApp extends Application { - } - - Factory factory; - - @Before - public void before() { - this.factory = new Factory(); - //ensure there are no word applications running. - while(true) { - try { - MsWordApp ao = this.factory.fetchObject(MsWordApp.class); - Application a = ao.queryInterface(Application.class); - try { - a.Quit(true, null, null); - try { - //wait for it to quit - Thread.sleep(100); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } catch (Exception e) { - e.printStackTrace();e.getCause().printStackTrace(); - } - } catch(Exception e) { - break; - } - } - } - - @After - public void after() { - try { - //wait for it to quit - Thread.sleep(100); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - - @Test - public void equals() { - MsWordApp comObj1 = this.factory.createObject(MsWordApp.class); - MsWordApp comObj2 = this.factory.fetchObject(MsWordApp.class); - - boolean res = comObj1.equals(comObj2); - - assertTrue(res); - - comObj1.Quit(false, null,null); - } - - @Test - public void notEquals() { - MsWordApp comObj1 = this.factory.createObject(MsWordApp.class); - MsWordApp comObj2 = this.factory.createObject(MsWordApp.class); - - boolean res = comObj1.equals(comObj2); - - assertFalse(res); - - comObj1.Quit(false, null,null); - } - - @Test - public void accessWhilstDisposing() { - MsWordApp comObj1 = this.factory.createObject(MsWordApp.class); - - //TODO: how to test this? - - this.factory.disposeAll(); - - } - -} diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/util/RunningObjectTable_Test.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/util/RunningObjectTable_Test.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/COM/util/RunningObjectTable_Test.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/COM/util/RunningObjectTable_Test.java 2017-03-14 19:31:03.000000000 +0000 @@ -12,6 +12,7 @@ */ package com.sun.jna.platform.win32.COM.util; +import com.sun.jna.Pointer; import static org.junit.Assert.*; import java.util.List; @@ -21,29 +22,25 @@ import org.junit.Test; import com.sun.jna.platform.win32.COM.COMException; -import com.sun.jna.platform.win32.COM.COMUtils; import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; import com.sun.jna.platform.win32.COM.util.annotation.ComObject; import com.sun.jna.platform.win32.COM.util.annotation.ComMethod; import com.sun.jna.platform.win32.COM.util.annotation.ComProperty; -import com.sun.jna.platform.win32.Guid.IID; import com.sun.jna.platform.win32.Ole32; -import com.sun.jna.platform.win32.Ole32Util; -import com.sun.jna.platform.win32.OleAuto; -import com.sun.jna.platform.win32.Variant; -import com.sun.jna.platform.win32.WinDef; -import com.sun.jna.platform.win32.WinNT; -import com.sun.jna.ptr.PointerByReference; public class RunningObjectTable_Test { + static { + ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true); + } + @ComInterface(iid="{00020970-0000-0000-C000-000000000046}") interface Application extends IUnknown { @ComProperty - boolean getVisible(); + Boolean getVisible(); @ComProperty - void setVisible(boolean value); + void setVisible(Boolean value); @ComMethod void Quit(boolean SaveChanges, Object OriginalFormat, Boolean RouteDocument); @@ -53,12 +50,13 @@ interface MsWordApp extends Application { } - Factory factory; + ObjectFactory factory; MsWordApp msWord; - + @Before public void before() { - this.factory = new Factory(); + Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED); + this.factory = new ObjectFactory(); //ensure there is only one word application running. while(true) { try { @@ -94,6 +92,8 @@ } catch (InterruptedException e) { e.printStackTrace(); } + factory.disposeAll(); + Ole32.INSTANCE.CoUninitialize(); } @Test diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/Crypt32Test.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/Crypt32Test.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/Crypt32Test.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/Crypt32Test.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,22 +1,23 @@ /* Copyright (c) 2010 Daniel Doubrovkine, All Rights Reserved - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * Lesser General Public License for more details. */ package com.sun.jna.platform.win32; -import junit.framework.TestCase; - +import com.sun.jna.Native; import com.sun.jna.platform.win32.WinCrypt.DATA_BLOB; import com.sun.jna.ptr.PointerByReference; +import junit.framework.TestCase; + /** * @author dblock[at]dblock[dot]org */ @@ -25,41 +26,71 @@ public static void main(String[] args) { junit.textui.TestRunner.run(Crypt32Test.class); } - + public void testCryptProtectUnprotectData() { DATA_BLOB pDataIn = new DATA_BLOB("hello world"); DATA_BLOB pDataEncrypted = new DATA_BLOB(); - assertTrue(Crypt32.INSTANCE.CryptProtectData(pDataIn, "description", - null, null, null, 0, pDataEncrypted)); - PointerByReference pDescription = new PointerByReference(); - DATA_BLOB pDataDecrypted = new DATA_BLOB(); - assertTrue(Crypt32.INSTANCE.CryptUnprotectData(pDataEncrypted, pDescription, - null, null, null, 0, pDataDecrypted)); - assertEquals("description", pDescription.getValue().getWideString(0)); - assertEquals("hello world", pDataDecrypted.pbData.getString(0)); - Kernel32.INSTANCE.LocalFree(pDataEncrypted.pbData); - Kernel32.INSTANCE.LocalFree(pDataDecrypted.pbData); - Kernel32.INSTANCE.LocalFree(pDescription.getValue()); + try { + assertTrue("CryptProtectData(Initial)", + Crypt32.INSTANCE.CryptProtectData(pDataIn, "description", + null, null, null, 0, pDataEncrypted)); + PointerByReference pDescription = new PointerByReference(); + try { + DATA_BLOB pDataDecrypted = new DATA_BLOB(); + try { + assertTrue("CryptProtectData(Crypt)", + Crypt32.INSTANCE.CryptUnprotectData(pDataEncrypted, pDescription, + null, null, null, 0, pDataDecrypted)); + assertEquals("description", pDescription.getValue().getWideString(0)); + assertEquals("hello world", pDataDecrypted.pbData.getString(0)); + } finally { + Kernel32Util.freeLocalMemory(pDataDecrypted.pbData); + } + } finally { + Kernel32Util.freeLocalMemory(pDescription.getValue()); + } + } finally { + Kernel32Util.freeLocalMemory(pDataEncrypted.pbData); + } } - + public void testCryptProtectUnprotectDataWithEntropy() { DATA_BLOB pDataIn = new DATA_BLOB("hello world"); + DATA_BLOB pEntropy = new DATA_BLOB("entropy"); DATA_BLOB pDataEncrypted = new DATA_BLOB(); - DATA_BLOB pEntropy = new DATA_BLOB("entropy"); - assertTrue(Crypt32.INSTANCE.CryptProtectData(pDataIn, "description", - pEntropy, null, null, 0, pDataEncrypted)); - PointerByReference pDescription = new PointerByReference(); - DATA_BLOB pDataDecrypted = new DATA_BLOB(); - // can't decrypt without entropy - assertFalse(Crypt32.INSTANCE.CryptUnprotectData(pDataEncrypted, pDescription, - null, null, null, 0, pDataDecrypted)); - // decrypt with entropy - assertTrue(Crypt32.INSTANCE.CryptUnprotectData(pDataEncrypted, pDescription, - pEntropy, null, null, 0, pDataDecrypted)); - assertEquals("description", pDescription.getValue().getWideString(0)); - assertEquals("hello world", pDataDecrypted.pbData.getString(0)); - Kernel32.INSTANCE.LocalFree(pDataEncrypted.pbData); - Kernel32.INSTANCE.LocalFree(pDataDecrypted.pbData); - Kernel32.INSTANCE.LocalFree(pDescription.getValue()); - } + try { + assertTrue("CryptProtectData(Initial)", + Crypt32.INSTANCE.CryptProtectData(pDataIn, "description", + pEntropy, null, null, 0, pDataEncrypted)); + PointerByReference pDescription = new PointerByReference(); + try { + DATA_BLOB pDataDecrypted = new DATA_BLOB(); + try { + // can't decrypt without entropy + assertFalse("CryptUnprotectData(NoEntropy)", + Crypt32.INSTANCE.CryptUnprotectData(pDataEncrypted, pDescription, + null, null, null, 0, pDataDecrypted)); + // decrypt with entropy + assertTrue("CryptUnprotectData(WithEntropy)", + Crypt32.INSTANCE.CryptUnprotectData(pDataEncrypted, pDescription, + pEntropy, null, null, 0, pDataDecrypted)); + assertEquals("description", pDescription.getValue().getWideString(0)); + assertEquals("hello world", pDataDecrypted.pbData.getString(0)); + } finally { + Kernel32Util.freeLocalMemory(pDataDecrypted.pbData); + } + } finally { + Kernel32Util.freeLocalMemory(pDescription.getValue()); + } + } finally { + Kernel32Util.freeLocalMemory(pDataEncrypted.pbData); + } + } + + public void testCertAddEncodedCertificateToSystemStore() { + // try to install a non-existent certificate + assertFalse("Attempting to install a non-existent certificate should have returned false and set GetLastError()", Crypt32.INSTANCE.CertAddEncodedCertificateToSystemStore("ROOT", null, 0)); + // should fail with "unexpected end of data" + assertEquals("GetLastError() should have been set to CRYPT_E_ASN1_EOD ('ASN.1 unexpected end of data' in WinCrypt.h)", WinCrypt.CRYPT_E_ASN1_EOD, Native.getLastError()); + } } \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/DdemlTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/DdemlTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/DdemlTest.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/DdemlTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,125 @@ + +package com.sun.jna.platform.win32; + +import com.sun.jna.Memory; +import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.Ddeml.DdeCallback; +import com.sun.jna.platform.win32.Ddeml.HDDEDATA; +import com.sun.jna.platform.win32.Ddeml.HSZ; +import com.sun.jna.platform.win32.WinDef.DWORDByReference; +import com.sun.jna.platform.win32.WinDef.PVOID; +import org.junit.Test; +import static org.junit.Assert.*; + +public class DdemlTest { + + @Test + public void testInitialization() { + DdeCallback callback = new Ddeml.DdeCallback() { + public WinDef.PVOID ddeCallback(int wType, int wFmt, Ddeml.HCONV hConv, Ddeml.HSZ hsz1, Ddeml.HSZ hsz2, Ddeml.HDDEDATA hData, BaseTSD.ULONG_PTR lData1, BaseTSD.ULONG_PTR lData2) { + return new PVOID(); + } + }; + + DWORDByReference pidInst = new DWORDByReference(); + int initResult = Ddeml.INSTANCE.DdeInitialize(pidInst, callback, Ddeml.APPCMD_CLIENTONLY, 0); + assertEquals(Ddeml.DMLERR_NO_ERROR, initResult); + boolean uninitResult = Ddeml.INSTANCE.DdeUninitialize(pidInst.getValue().intValue()); + assertTrue(uninitResult); + } + + + @Test + public void testStringHandling() { + DdeCallback callback = new Ddeml.DdeCallback() { + public WinDef.PVOID ddeCallback(int wType, int wFmt, Ddeml.HCONV hConv, Ddeml.HSZ hsz1, Ddeml.HSZ hsz2, Ddeml.HDDEDATA hData, BaseTSD.ULONG_PTR lData1, BaseTSD.ULONG_PTR lData2) { + return new PVOID(); + } + }; + + DWORDByReference pidInst = new DWORDByReference(); + int initResult = Ddeml.INSTANCE.DdeInitialize(pidInst, callback, Ddeml.APPCMD_CLIENTONLY, 0); + assertEquals(Ddeml.DMLERR_NO_ERROR, initResult); + + HSZ handle = Ddeml.INSTANCE.DdeCreateStringHandle(pidInst.getValue().intValue(), "Test", Ddeml.CP_WINUNICODE); + assertNotNull(handle); + + + Memory mem = new Memory(256 * 2); // String in DDE can not exceed 255 Chars + Ddeml.INSTANCE.DdeQueryString(pidInst.getValue().intValue(), handle, mem, 256, Ddeml.CP_WINUNICODE); + + assertEquals("Test", mem.getWideString(0)); + + synchronized(mem) {} + + assertTrue(Ddeml.INSTANCE.DdeFreeStringHandle(pidInst.getValue().intValue(), handle)); + + // Test overlong creation -- according to documentation this must fail + StringBuilder testString = new StringBuilder(); + for(int i = 0; i < 30; i++) { + testString.append("0123456789"); + } + + HSZ handle2 = Ddeml.INSTANCE.DdeCreateStringHandle(pidInst.getValue().intValue(), testString.toString(), Ddeml.CP_WINUNICODE); + assertNull(handle2); + + boolean uninitResult = Ddeml.INSTANCE.DdeUninitialize(pidInst.getValue().intValue()); + assertTrue(uninitResult); + } + + @Test + public void testGetLastError() { + int errorCode = Ddeml.INSTANCE.DdeGetLastError(0); + assertEquals(Ddeml.DMLERR_INVALIDPARAMETER, errorCode); + } + + @Test + public void testMemoryHandling() { + DdeCallback callback = new Ddeml.DdeCallback() { + public WinDef.PVOID ddeCallback(int wType, int wFmt, Ddeml.HCONV hConv, Ddeml.HSZ hsz1, Ddeml.HSZ hsz2, Ddeml.HDDEDATA hData, BaseTSD.ULONG_PTR lData1, BaseTSD.ULONG_PTR lData2) { + return new PVOID(); + } + }; + + DWORDByReference pidInst = new DWORDByReference(); + int initResult = Ddeml.INSTANCE.DdeInitialize(pidInst, callback, Ddeml.APPCMD_CLIENTONLY, 0); + assertEquals(Ddeml.DMLERR_NO_ERROR, initResult); + + // Acquire dummy handle + HSZ hsz = Ddeml.INSTANCE.DdeCreateStringHandle(pidInst.getValue().intValue(), "Dummy", Ddeml.CP_WINUNICODE); + + String testStringPart1 = "Hallo "; + String testStringPart2 = "Welt"; + + // Create Handle + Memory mem = new Memory(256 * 2); // String in DDE can not exceed 255 Chars + mem.setWideString(0, testStringPart1); + HDDEDATA data = Ddeml.INSTANCE.DdeCreateDataHandle(pidInst.getValue().intValue(), mem, testStringPart1.length() * 2, 0, hsz, WinUser.CF_UNICODETEXT, Ddeml.HDATA_APPOWNED); + + mem.setWideString(0, testStringPart2); + Ddeml.INSTANCE.DdeAddData(data, mem, (testStringPart2.length() + 1) * 2, testStringPart1.length() * 2); + + DWORDByReference dataSize = new DWORDByReference(); + Pointer resultPointer = Ddeml.INSTANCE.DdeAccessData(data, dataSize); + + assertEquals((testStringPart1.length() + testStringPart2.length() + 1) * 2, dataSize.getValue().intValue()); + assertEquals(testStringPart1 + testStringPart2, resultPointer.getWideString(0)); + + boolean result = Ddeml.INSTANCE.DdeUnaccessData(data); + + int readSize = Ddeml.INSTANCE.DdeGetData(data, mem, (int) mem.size(), 0); + assertEquals((testStringPart1.length() + testStringPart2.length() + 1) * 2, readSize); + assertEquals(testStringPart1 + testStringPart2, mem.getWideString(0)); + + assertTrue(result); + + result = Ddeml.INSTANCE.DdeFreeDataHandle(data); + + assertTrue(result); + + synchronized(mem) {} + + result = Ddeml.INSTANCE.DdeUninitialize(pidInst.getValue().intValue()); + assertTrue(result); + } +} diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/DdemlUtilTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/DdemlUtilTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/DdemlUtilTest.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/DdemlUtilTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,807 @@ + +package com.sun.jna.platform.win32; + +import com.sun.jna.Memory; +import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.BaseTSD.ULONG_PTR; +import com.sun.jna.platform.win32.Ddeml.CONVINFO; +import com.sun.jna.platform.win32.Ddeml.HCONV; +import com.sun.jna.platform.win32.Ddeml.HDDEDATA; +import com.sun.jna.platform.win32.Ddeml.HSZ; +import com.sun.jna.platform.win32.DdemlUtil.DdeAdapter; +import com.sun.jna.platform.win32.DdemlUtil.IDdeConnection; +import com.sun.jna.platform.win32.DdemlUtil.StandaloneDdeClient; +import java.io.Closeable; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; +import static org.hamcrest.core.Is.is; +import org.junit.Assert; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import org.junit.BeforeClass; +import org.junit.Test; +import com.sun.jna.platform.win32.DdemlUtil.AdvstartHandler; +import com.sun.jna.platform.win32.DdemlUtil.ConnectHandler; +import com.sun.jna.platform.win32.DdemlUtil.AdvreqHandler; +import com.sun.jna.platform.win32.DdemlUtil.RequestHandler; +import com.sun.jna.platform.win32.DdemlUtil.WildconnectHandler; +import com.sun.jna.platform.win32.DdemlUtil.AdvdataHandler; +import com.sun.jna.platform.win32.DdemlUtil.ConnectConfirmHandler; +import com.sun.jna.platform.win32.DdemlUtil.DisconnectHandler; +import com.sun.jna.platform.win32.DdemlUtil.RegisterHandler; +import com.sun.jna.platform.win32.DdemlUtil.XactCompleteHandler; +import com.sun.jna.platform.win32.DdemlUtil.ExecuteHandler; +import com.sun.jna.platform.win32.DdemlUtil.PokeHandler; + + +public class DdemlUtilTest { + @BeforeClass + public static void init() { + Logger rootLogger = Logger.getLogger(""); + rootLogger.getHandlers()[0].setLevel(Level.ALL); + Logger.getLogger(DdeAdapter.class.getName()).setLevel(Level.FINE); + } + + @Test + public void testNameService() throws InterruptedException { + final String serviceName = "TestService"; + final CountDownLatch latch = new CountDownLatch(1); + StandaloneDdeClient client = null; + StandaloneDdeClient server = null; + + try { + client = new StandaloneDdeClient() { + private final RegisterHandler registerHandler = new RegisterHandler() { + public void onRegister(int transactionType, HSZ baseServiceName, HSZ instanceSpecificServiceName) { + if (serviceName.equals(queryString(baseServiceName))) { + latch.countDown(); + } + } + }; + + { + registerRegisterHandler(registerHandler); + this.initialize(Ddeml.APPCMD_CLIENTONLY); + } + }; + + server = new StandaloneDdeClient() { + { + this.initialize(Ddeml.APPCMD_FILTERINITS + | Ddeml.CBF_SKIP_ALLNOTIFICATIONS + | Ddeml.CBF_FAIL_ALLSVRXACTIONS); + } + }; + + server.nameService(serviceName, Ddeml.DNS_REGISTER); + + Assert.assertTrue(latch.await(5, TimeUnit.SECONDS)); + } finally { + closeQuitely(server); + closeQuitely(client); + } + } + + @Test + public void testConnectDisconnect() throws InterruptedException { + final String serviceName = "TestService"; + final String topicName = "TestTopic"; + final CountDownLatch connectLatch = new CountDownLatch(1); + final CountDownLatch disconnectLatch = new CountDownLatch(1); + + StandaloneDdeClient client = null; + StandaloneDdeClient server = null; + + try { + client = new StandaloneDdeClient() { + { + this.initialize(Ddeml.APPCMD_CLIENTONLY + | Ddeml.CBF_SKIP_REGISTRATIONS + | Ddeml.CBF_SKIP_UNREGISTRATIONS); + } + }; + server = new StandaloneDdeClient() { + private final ConnectHandler connectHandler = new ConnectHandler() { + public boolean onConnect(int transactionType, HSZ topic, HSZ service, Ddeml.CONVCONTEXT convcontext, boolean sameInstance) { + return topicName.equals(queryString(topic)); + } + }; + + private final ConnectConfirmHandler connectConfirmHandler = new ConnectConfirmHandler() { + public void onConnectConfirm(int transactionType, HCONV hconv, HSZ topic, HSZ service, boolean sameInstance) { + if (topicName.equals(queryString(topic))) { + connectLatch.countDown(); + } + } + }; + + private final DisconnectHandler disconnectHandler = new DisconnectHandler() { + public void onDisconnect(int transactionType, HCONV hconv, boolean sameInstance) { + disconnectLatch.countDown(); + } + }; + + { + registerConnectHandler(connectHandler); + registerConnectConfirmHandler(connectConfirmHandler); + registerDisconnectHandler(disconnectHandler); + this.initialize(Ddeml.APPCMD_FILTERINITS + | Ddeml.CBF_SKIP_REGISTRATIONS + | Ddeml.CBF_SKIP_UNREGISTRATIONS + ); + } + }; + + server.nameService(serviceName, Ddeml.DNS_REGISTER); + + + IDdeConnection connection = client.connect(serviceName, topicName, null); + assertTrue("Failed to connect", connectLatch.await(5, TimeUnit.SECONDS)); + connection.close(); + assertTrue("Failed to disconnect", disconnectLatch.await(5, TimeUnit.SECONDS)); + + } finally { + closeQuitely(client); + closeQuitely(server); + } + } + + @Test + public void testConnectListDisconnectListQueryNextServer() throws InterruptedException { + final String serviceName = "TestService"; + final String topicName = "TestTopic"; + final CountDownLatch connectLatch1 = new CountDownLatch(1); + final CountDownLatch disconnectLatch1 = new CountDownLatch(1); + final CountDownLatch connectLatch2 = new CountDownLatch(1); + final CountDownLatch disconnectLatch2 = new CountDownLatch(1); + + StandaloneDdeClient client = null; + StandaloneDdeClient server1 = null; + StandaloneDdeClient server2 = null; + + try { + client = new StandaloneDdeClient() { + { + this.initialize(Ddeml.APPCMD_CLIENTONLY + | Ddeml.CBF_SKIP_REGISTRATIONS + | Ddeml.CBF_SKIP_UNREGISTRATIONS); + } + }; + + class Server extends StandaloneDdeClient { + private final CountDownLatch connectLatch; + private final CountDownLatch disconnectLatch; + + private final ConnectHandler connectHandler = new ConnectHandler() { + public boolean onConnect(int transactionType, HSZ topic, HSZ service, Ddeml.CONVCONTEXT convcontext, boolean sameInstance) { + return topicName.equals(queryString(topic)); + } + }; + + private final ConnectConfirmHandler connectConfirmHandler = new ConnectConfirmHandler() { + public void onConnectConfirm(int transactionType, Ddeml.HCONV hconv, HSZ topic, HSZ service, boolean sameInstance) { + if (topicName.equals(queryString(topic))) { + connectLatch.countDown(); + } + } + }; + + private final DisconnectHandler disconnectHandler = new DisconnectHandler() { + public void onDisconnect(int transactionType, HCONV hconv, boolean sameInstance) { + disconnectLatch.countDown(); + } + }; + + private final WildconnectHandler wildconnectHandler = new WildconnectHandler() { + public List onWildconnect(int transactionType, HSZ topic, HSZ service, Ddeml.CONVCONTEXT convcontext, boolean sameInstance) { + return Collections.singletonList(new Ddeml.HSZPAIR(service, topic)); + } + }; + + public Server(CountDownLatch connectLatch, CountDownLatch disconnectLatch) { + registerConnectHandler(connectHandler); + registerConnectConfirmHandler(connectConfirmHandler); + registerDisconnectHandler(disconnectHandler); + registerWildconnectHandler(wildconnectHandler); + this.initialize(Ddeml.APPCMD_FILTERINITS + | Ddeml.CBF_SKIP_REGISTRATIONS + | Ddeml.CBF_SKIP_UNREGISTRATIONS + ); + this.connectLatch = connectLatch; + this.disconnectLatch = disconnectLatch; + } + }; + + server1 = new Server(connectLatch1, disconnectLatch1); + server2 = new Server(connectLatch2, disconnectLatch2); + + server1.nameService(serviceName, Ddeml.DNS_REGISTER); + server2.nameService(serviceName, Ddeml.DNS_REGISTER); + + DdemlUtil.IDdeConnectionList connectionList = client.connectList(serviceName, topicName, null, null); + + IDdeConnection con1 = connectionList.queryNextServer(null); + assertNotNull(con1); + IDdeConnection con2 = connectionList.queryNextServer(con1); + assertNotNull(con2); + IDdeConnection con3 = connectionList.queryNextServer(con2); + assertNull(con3); + + connectionList.close(); + + assertTrue(connectLatch1.await(5, TimeUnit.SECONDS)); + assertTrue(connectLatch2.await(5, TimeUnit.SECONDS)); + assertTrue(disconnectLatch1.await(5, TimeUnit.SECONDS)); + assertTrue(disconnectLatch2.await(5, TimeUnit.SECONDS)); + } finally { + closeQuitely(client); + closeQuitely(server1); + closeQuitely(server2); + } + } + + @Test + public void testExecute() throws InterruptedException { + final String serviceName = "TestService"; + final String topicName = "TestTopic"; + final String testExecute = "Execute�������"; + final CountDownLatch executeReceived = new CountDownLatch(1); + + StandaloneDdeClient client = null; + StandaloneDdeClient server = null; + + try { + client = new StandaloneDdeClient() { + { + this.initialize(Ddeml.APPCMD_CLIENTONLY + | Ddeml.CBF_SKIP_REGISTRATIONS + | Ddeml.CBF_SKIP_UNREGISTRATIONS); + } + }; + + server = new StandaloneDdeClient() { + + private final ConnectHandler connectHandler = new ConnectHandler() { + public boolean onConnect(int transactionType, HSZ topic, HSZ service, Ddeml.CONVCONTEXT convcontext, boolean sameInstance) { + return topicName.equals(queryString(topic)); + } + }; + + private final ExecuteHandler executeHandler = new ExecuteHandler() { + public int onExecute(int transactionType, HCONV hconv, HSZ topic, Ddeml.HDDEDATA commandStringData) { + Pointer[] pointer = new Pointer[] { accessData(commandStringData, null) }; + try { + String commandString = pointer[0].getWideString(0); + if(testExecute.equals(commandString) && queryString(topic).equals(topicName)) { + executeReceived.countDown(); + return Ddeml.DDE_FACK; + } + } finally { + synchronized(pointer) { + unaccessData(commandStringData); + } + } + return Ddeml.DDE_FNOTPROCESSED; + } + }; + + { + registerConnectHandler(connectHandler); + registerExecuteHandler(executeHandler); + this.initialize(Ddeml.APPCMD_FILTERINITS + | Ddeml.CBF_SKIP_ALLNOTIFICATIONS + ); + } + }; + + server.nameService(serviceName, Ddeml.DNS_REGISTER); + + IDdeConnection con = client.connect(serviceName, topicName, null); + con.execute(testExecute, 5 * 1000, null, null); + + assertTrue(executeReceived.await(5, TimeUnit.SECONDS)); + } finally { + closeQuitely(client); + closeQuitely(server); + } + } + + @Test + public void testPoke() throws InterruptedException { + final String serviceName = "TestService"; + final String topicName = "TestTopic"; + final String itemName = "TestItem"; + final String testValue = "Execute�������"; + final CountDownLatch pokeReceived = new CountDownLatch(1); + + StandaloneDdeClient client = null; + StandaloneDdeClient server = null; + + try { + client = new StandaloneDdeClient() { + { + this.initialize(Ddeml.APPCMD_CLIENTONLY + | Ddeml.CBF_SKIP_REGISTRATIONS + | Ddeml.CBF_SKIP_UNREGISTRATIONS); + } + }; + + server = new StandaloneDdeClient() { + private final ConnectHandler connectHandler = new ConnectHandler() { + public boolean onConnect(int transactionType, HSZ topic, HSZ service, Ddeml.CONVCONTEXT convcontext, boolean sameInstance) { + return topicName.equals(queryString(topic)); + } + }; + + private final PokeHandler pokeHandler = new PokeHandler() { + @Override + public int onPoke(int transactionType, int dataFormat, HCONV hconv, HSZ topic, HSZ item, Ddeml.HDDEDATA hdata) { + Pointer[] pointer = new Pointer[]{accessData(hdata, null)}; + try { + String commandString = pointer[0].getWideString(0); + if (testValue.equals(commandString) && queryString(topic).equals(topicName) && queryString(item).equals(itemName)) { + pokeReceived.countDown(); + return Ddeml.DDE_FACK; + } + } finally { + synchronized (pointer) { + } + } + return Ddeml.DDE_FNOTPROCESSED; + } + }; + + { + registerConnectHandler(connectHandler); + registerPokeHandler(pokeHandler); + this.initialize(Ddeml.APPCMD_FILTERINITS + | Ddeml.CBF_SKIP_ALLNOTIFICATIONS + ); + } + }; + + server.nameService(serviceName, Ddeml.DNS_REGISTER); + + IDdeConnection con = client.connect(serviceName, topicName, null); + Memory mem = new Memory( (testValue.length() + 1 ) * 2); + mem.setWideString(0, testValue); + con.poke(mem, (int) mem.size(), itemName, WinUser.CF_UNICODETEXT, 5 * 1000, null, null); + + assertTrue(pokeReceived.await(5, TimeUnit.SECONDS)); + } finally { + closeQuitely(client); + closeQuitely(server); + } + } + + @Test + public void testRequest() throws InterruptedException { + final String serviceName = "TestService"; + final String topicName = "TestTopic"; + final String itemName = "TestItem"; + final String testValue = "Execute�������"; + final CountDownLatch pokeReceived = new CountDownLatch(1); + + StandaloneDdeClient client = null; + StandaloneDdeClient server = null; + + try { + client = new StandaloneDdeClient() { + { + this.initialize(Ddeml.APPCMD_CLIENTONLY + | Ddeml.CBF_SKIP_REGISTRATIONS + | Ddeml.CBF_SKIP_UNREGISTRATIONS); + } + }; + + server = new StandaloneDdeClient() { + private final ConnectHandler connectHandler = new ConnectHandler() { + public boolean onConnect(int transactionType, HSZ topic, HSZ service, Ddeml.CONVCONTEXT convcontext, boolean sameInstance) { + return topicName.equals(queryString(topic)); + } + }; + + private final RequestHandler requestHandler = new RequestHandler() { + public HDDEDATA onRequest(int transactionType, int dataFormat, HCONV hconv, HSZ topic, HSZ item) { + if (dataFormat == WinUser.CF_UNICODETEXT && queryString(topic).equals(topicName) && queryString(item).equals(itemName)) { + Memory mem = new Memory((testValue.length() + 1) * 2); + mem.setWideString(0, testValue); + HDDEDATA result = createDataHandle(mem, (int) mem.size(), 0, item, dataFormat, 0); + pokeReceived.countDown(); + return result; + } else { + return null; + } + } + }; + + { + registerConnectHandler(connectHandler); + registerRequestHandler(requestHandler); + this.initialize(Ddeml.APPCMD_FILTERINITS + | Ddeml.CBF_SKIP_ALLNOTIFICATIONS + ); + } + }; + + server.nameService(serviceName, Ddeml.DNS_REGISTER); + + IDdeConnection con = client.connect(serviceName, topicName, null); + HDDEDATA data = con.request(itemName, WinUser.CF_UNICODETEXT, 5 * 1000, null, null); + try { + try { + Pointer pointer = server.accessData(data, null); + assertThat(pointer.getWideString(0), is(testValue)); + } finally { + server.unaccessData(data); + } + } finally { + server.freeDataHandle(data); + } + + assertTrue(pokeReceived.await(5, TimeUnit.SECONDS)); + } finally { + closeQuitely(client); + closeQuitely(server); + } + } + + @Test + public void testAbandonTransaction() throws InterruptedException { + final String serviceName = "TestService"; + final String topicName = "TestTopic"; + final String testExecute = "Execute�������"; + final CountDownLatch allTransactionsInvoked = new CountDownLatch(1); + final CountDownLatch executesProcessed = new CountDownLatch(3); + + StandaloneDdeClient client = null; + StandaloneDdeClient server = null; + + try { + client = new StandaloneDdeClient() { + private final XactCompleteHandler xactCompleteHandler = new XactCompleteHandler() { + public void onXactComplete(int transactionType, int dataFormat, HCONV hConv, HSZ topic, HSZ item, HDDEDATA hdata, ULONG_PTR transactionIdentifier, ULONG_PTR statusFlag) { + executesProcessed.countDown(); + } + }; + + { + registerXactCompleteHandler(xactCompleteHandler); + this.initialize(Ddeml.APPCMD_CLIENTONLY + | Ddeml.CBF_SKIP_REGISTRATIONS + | Ddeml.CBF_SKIP_UNREGISTRATIONS); + } + }; + + server = new StandaloneDdeClient() { + private final ConnectHandler connectHandler = new ConnectHandler() { + public boolean onConnect(int transactionType, HSZ topic, HSZ service, Ddeml.CONVCONTEXT convcontext, boolean sameInstance) { + return topicName.equals(queryString(topic)); + } + }; + + private final ExecuteHandler executeHandler = new ExecuteHandler() { + public int onExecute(int transactionType, HCONV hconv, HSZ topic, Ddeml.HDDEDATA commandStringData) { + try { + if(! allTransactionsInvoked.await(5, TimeUnit.SECONDS)) { + return Ddeml.DDE_FNOTPROCESSED; + } + Pointer[] pointer = new Pointer[] { accessData(commandStringData, null) }; + try { + String commandString = pointer[0].getWideString(0); + if(testExecute.equals(commandString) && queryString(topic).equals(topicName)) { + return Ddeml.DDE_FACK; + } + } finally { + synchronized(pointer) { + unaccessData(commandStringData); + } + } + return Ddeml.DDE_FNOTPROCESSED; + } catch (InterruptedException ex) { + Logger.getLogger(DdemlUtilTest.class.getName()).log(Level.SEVERE, null, ex); + return Ddeml.DDE_FNOTPROCESSED; + } + } + }; + + { + registerConnectHandler(connectHandler); + registerExecuteHandler(executeHandler); + this.initialize(Ddeml.APPCMD_FILTERINITS + | Ddeml.CBF_SKIP_ALLNOTIFICATIONS + ); + } + }; + + server.nameService(serviceName, Ddeml.DNS_REGISTER); + + IDdeConnection con = client.connect(serviceName, topicName, null); + + WinDef.DWORDByReference result = new WinDef.DWORDByReference(); + con.execute(testExecute, Ddeml.TIMEOUT_ASYNC, result, null); + con.execute(testExecute, Ddeml.TIMEOUT_ASYNC, result, null); + int transactionId2 = result.getValue().intValue(); + con.execute(testExecute, Ddeml.TIMEOUT_ASYNC, result, null); + + con.abandonTransaction(transactionId2); + + allTransactionsInvoked.countDown(); + + assertFalse(executesProcessed.await(2, TimeUnit.SECONDS)); + assertThat(executesProcessed.getCount(), is(1L)); + } finally { + closeQuitely(client); + closeQuitely(server); + } + } + + @Test + public void testEnableCallback() throws InterruptedException { + final String serviceName = "TestService"; + final String topicName = "TestTopic"; + final String testExecute = "Execute�������"; + final CountDownLatch executesProcessed = new CountDownLatch(3); + + StandaloneDdeClient client = null; + StandaloneDdeClient server = null; + + try { + client = new StandaloneDdeClient() { + private final XactCompleteHandler xactCompleteHandler = new XactCompleteHandler() { + public void onXactComplete(int transactionType, int dataFormat, HCONV hConv, HSZ topic, HSZ item, HDDEDATA hdata, ULONG_PTR transactionIdentifier, ULONG_PTR statusFlag) { + executesProcessed.countDown(); + } + + }; + + { + registerXactCompleteHandler(xactCompleteHandler); + this.initialize(Ddeml.APPCMD_CLIENTONLY + | Ddeml.CBF_SKIP_REGISTRATIONS + | Ddeml.CBF_SKIP_UNREGISTRATIONS); + } + }; + + server = new StandaloneDdeClient() { + private final ConnectHandler connectHandler = new ConnectHandler() { + public boolean onConnect(int transactionType, HSZ topic, HSZ service, Ddeml.CONVCONTEXT convcontext, boolean sameInstance) { + return topicName.equals(queryString(topic)); + } + }; + + + private final ExecuteHandler executeHandler = new ExecuteHandler() { + public int onExecute(int transactionType, HCONV hconv, HSZ topic, Ddeml.HDDEDATA commandStringData) { + Pointer[] pointer = new Pointer[] { accessData(commandStringData, null) }; + try { + String commandString = pointer[0].getWideString(0); + if(testExecute.equals(commandString) && queryString(topic).equals(topicName)) { + return Ddeml.DDE_FACK; + } + } finally { + synchronized(pointer) { + unaccessData(commandStringData); + } + } + return Ddeml.DDE_FNOTPROCESSED; + } + }; + + { + registerConnectHandler(connectHandler); + registerExecuteHandler(executeHandler); + this.initialize(Ddeml.APPCMD_FILTERINITS + | Ddeml.CBF_SKIP_ALLNOTIFICATIONS + ); + } + }; + + server.nameService(serviceName, Ddeml.DNS_REGISTER); + server.enableCallback(Ddeml.EC_DISABLE); + + assertThat(server.enableCallback(Ddeml.EC_QUERYWAITING), is(false)); + + IDdeConnection con = client.connect(serviceName, topicName, null); + + WinDef.DWORDByReference result = new WinDef.DWORDByReference(); + con.execute(testExecute, Ddeml.TIMEOUT_ASYNC, result, null); + con.execute(testExecute, Ddeml.TIMEOUT_ASYNC, result, null); + con.execute(testExecute, Ddeml.TIMEOUT_ASYNC, result, null); + + assertThat(server.enableCallback(Ddeml.EC_QUERYWAITING), is(true)); + + server.enableCallback(Ddeml.EC_ENABLEALL); + + assertTrue(executesProcessed.await(3, TimeUnit.SECONDS)); + } finally { + closeQuitely(client); + closeQuitely(server); + } + } + + @Test + public void testQueryConvInfoSetUserHandle() throws InterruptedException { + final String serviceName = "TestService"; + final String topicName = "TestTopic"; + final String testExecute = "Execute�������"; + final CountDownLatch executesProcessed = new CountDownLatch(1); + + StandaloneDdeClient client = null; + StandaloneDdeClient server = null; + + try { + client = new StandaloneDdeClient() { + private final XactCompleteHandler xactCompleteHandler = new XactCompleteHandler() { + public void onXactComplete(int transactionType, int dataFormat, HCONV hConv, HSZ topic, HSZ item, HDDEDATA hdata, ULONG_PTR transactionIdentifier, ULONG_PTR statusFlag) { + CONVINFO convInfo = wrap(hConv).queryConvInfo(transactionIdentifier.intValue()); + if(convInfo.hUser.intValue() == 42) { + executesProcessed.countDown(); + } + } + + }; + + { + registerXactCompleteHandler(xactCompleteHandler); + this.initialize(Ddeml.APPCMD_CLIENTONLY + | Ddeml.CBF_SKIP_REGISTRATIONS + | Ddeml.CBF_SKIP_UNREGISTRATIONS); + } + }; + + server = new StandaloneDdeClient() { + private final ConnectHandler connectHandler = new ConnectHandler() { + public boolean onConnect(int transactionType, HSZ topic, HSZ service, Ddeml.CONVCONTEXT convcontext, boolean sameInstance) { + return topicName.equals(queryString(topic)); + } + }; + + private final ExecuteHandler executeHandler = new ExecuteHandler() { + public int onExecute(int transactionType, HCONV hconv, HSZ topic, Ddeml.HDDEDATA commandStringData) { + Pointer[] pointer = new Pointer[] { accessData(commandStringData, null) }; + try { + String commandString = pointer[0].getWideString(0); + if(testExecute.equals(commandString) && queryString(topic).equals(topicName)) { + return Ddeml.DDE_FACK; + } + } finally { + synchronized(pointer) { + unaccessData(commandStringData); + } + } + return Ddeml.DDE_FNOTPROCESSED; + } + }; + + { + registerConnectHandler(connectHandler); + registerExecuteHandler(executeHandler); + this.initialize(Ddeml.APPCMD_FILTERINITS + | Ddeml.CBF_SKIP_ALLNOTIFICATIONS + ); + } + }; + + server.nameService(serviceName, Ddeml.DNS_REGISTER); + + IDdeConnection con = client.connect(serviceName, topicName, null); + + con.execute(testExecute, Ddeml.TIMEOUT_ASYNC, null, new BaseTSD.DWORD_PTR(42L)); + + assertTrue(executesProcessed.await(3, TimeUnit.SECONDS)); + } finally { + closeQuitely(client); + closeQuitely(server); + } + } + + @Test + public void testAdvise() throws InterruptedException { + final String serviceName = "TestService"; + final String topicName = "TestTopic"; + final String itemName = "TestItem"; + final String testValue = "Execute�������"; + final CountDownLatch adviseStartReceived = new CountDownLatch(1); + final CountDownLatch adviseDataRequestReceived = new CountDownLatch(1); + final CountDownLatch adviseDataReceived = new CountDownLatch(1); + + StandaloneDdeClient client = null; + StandaloneDdeClient server = null; + + try { + client = new StandaloneDdeClient() { + private final AdvdataHandler advdataHandler = new DdemlUtil.AdvdataHandler() { + public int onAdvdata(int transactionType, int dataFormat, HCONV hconv, HSZ topic, HSZ item, HDDEDATA hdata) { + if (dataFormat == WinUser.CF_UNICODETEXT + && topicName.equals(queryString(topic)) + && itemName.equals(queryString(item))) { + Pointer pointer = accessData(hdata, null); + try { + if (testValue.equals(pointer.getWideString(0))) { + adviseDataReceived.countDown(); + } + } finally { + unaccessData(hdata); + } + } + return Ddeml.DDE_FACK; + } + }; + + { + registerAdvdataHandler(advdataHandler); + this.initialize(Ddeml.APPCMD_CLIENTONLY + | Ddeml.CBF_SKIP_REGISTRATIONS + | Ddeml.CBF_SKIP_UNREGISTRATIONS); + } + }; + + server = new StandaloneDdeClient() { + private final ConnectHandler connectHandler = new ConnectHandler() { + public boolean onConnect(int transactionType, HSZ topic, HSZ service, Ddeml.CONVCONTEXT convcontext, boolean sameInstance) { + return topicName.equals(queryString(topic)); + } + }; + + private final AdvreqHandler advreqHandler = new AdvreqHandler() { + public HDDEDATA onAdvreq(int transactionType, int dataFormat, HCONV hconv, HSZ topic, HSZ item, int count) { + adviseDataRequestReceived.countDown(); + Memory mem = new Memory( (testValue.length() + 1) * 2); + mem.setWideString(0, testValue); + return createDataHandle(mem, (int) mem.size(), 0, item, dataFormat, 0); + } + }; + + private final AdvstartHandler advstartHandler = new AdvstartHandler() { + public boolean onAdvstart(int transactionType, int dataFormat, HCONV hconv, HSZ topic, HSZ item) { + adviseStartReceived.countDown(); + return dataFormat == WinUser.CF_UNICODETEXT + && topicName.equals(queryString(topic)) + && itemName.equals(queryString(item)); + } + }; + + { + registerConnectHandler(connectHandler); + registerAdvReqHandler(advreqHandler); + registerAdvstartHandler(advstartHandler); + this.initialize(Ddeml.APPCMD_FILTERINITS + | Ddeml.CBF_SKIP_ALLNOTIFICATIONS + ); + } + }; + + server.nameService(serviceName, Ddeml.DNS_REGISTER); + + IDdeConnection con = client.connect(serviceName, topicName, null); + con.advstart(itemName, WinUser.CF_UNICODETEXT, 5 * 1000, null, null); + + assertTrue(adviseStartReceived.await(5, TimeUnit.SECONDS)); + + server.postAdvise(topicName, itemName); + + assertTrue(adviseDataRequestReceived.await(5, TimeUnit.SECONDS)); + assertTrue(adviseDataReceived.await(5, TimeUnit.SECONDS)); + } finally { + closeQuitely(client); + closeQuitely(server); + } + } + + private static void closeQuitely(Closeable closeable) { + if (closeable != null) { + try { + closeable.close(); + } catch (Exception ex) { + } + } + } +} diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/Dxva2Test.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/Dxva2Test.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/Dxva2Test.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/Dxva2Test.java 2017-03-14 19:31:03.000000000 +0000 @@ -21,7 +21,6 @@ import static org.junit.Assume.*; import com.sun.jna.Memory; -import com.sun.jna.platform.win32.Dxva2; import com.sun.jna.platform.win32.HighLevelMonitorConfigurationAPI.MC_COLOR_TEMPERATURE; import com.sun.jna.platform.win32.HighLevelMonitorConfigurationAPI.MC_DISPLAY_TECHNOLOGY_TYPE; import com.sun.jna.platform.win32.HighLevelMonitorConfigurationAPI.MC_DRIVE_TYPE; @@ -30,13 +29,12 @@ import com.sun.jna.platform.win32.HighLevelMonitorConfigurationAPI.MC_SIZE_TYPE; import com.sun.jna.platform.win32.LowLevelMonitorConfigurationAPI.MC_TIMING_REPORT; import com.sun.jna.platform.win32.PhysicalMonitorEnumerationAPI.PHYSICAL_MONITOR; -import com.sun.jna.platform.win32.User32; import com.sun.jna.platform.win32.WTypes.LPSTR; +import com.sun.jna.platform.win32.WinDef.BOOL; import com.sun.jna.platform.win32.WinDef.DWORD; import com.sun.jna.platform.win32.WinDef.DWORDByReference; import com.sun.jna.platform.win32.WinDef.POINT; import com.sun.jna.platform.win32.WinNT.HANDLE; -import com.sun.jna.platform.win32.WinUser; import com.sun.jna.platform.win32.WinUser.HMONITOR; @@ -51,7 +49,7 @@ @Before public void setUp() { - HMONITOR hMonitor = User32.INSTANCE.MonitorFromPoint(new POINT(0, 0), WinUser.MONITOR_DEFAULTTOPRIMARY); + HMONITOR hMonitor = User32.INSTANCE.MonitorFromWindow(User32.INSTANCE.GetDesktopWindow(), WinUser.MONITOR_DEFAULTTOPRIMARY); DWORDByReference pdwNumberOfPhysicalMonitors = new DWORDByReference(); assertTrue(Dxva2.INSTANCE.GetNumberOfPhysicalMonitorsFromHMONITOR(hMonitor, pdwNumberOfPhysicalMonitors).booleanValue()); @@ -136,11 +134,15 @@ // the method returns FALSE if the monitor driver doesn't support it, // but verifies that the JNA mapping is correct (no exception) DWORDByReference pdwCapabilitiesStringLengthInCharacters = new DWORDByReference(); - Dxva2.INSTANCE.GetCapabilitiesStringLength(hPhysicalMonitor, pdwCapabilitiesStringLengthInCharacters); - DWORD capStrLen = pdwCapabilitiesStringLengthInCharacters.getValue(); - - LPSTR pszASCIICapabilitiesString = new LPSTR(new Memory(capStrLen.intValue())); - Dxva2.INSTANCE.CapabilitiesRequestAndCapabilitiesReply(hPhysicalMonitor, pszASCIICapabilitiesString, capStrLen); + BOOL success = Dxva2.INSTANCE.GetCapabilitiesStringLength(hPhysicalMonitor, pdwCapabilitiesStringLengthInCharacters); + if(success.booleanValue()) { + // VirtualBox is known to report an empty string + DWORD capStrLen = pdwCapabilitiesStringLengthInCharacters.getValue(); + LPSTR pszASCIICapabilitiesString = new LPSTR(new Memory(capStrLen.intValue())); + Dxva2.INSTANCE.CapabilitiesRequestAndCapabilitiesReply(hPhysicalMonitor, pszASCIICapabilitiesString, capStrLen); + } else { + System.err.println("GetCapabilitiesStringLength failed with errorcode: " + Kernel32.INSTANCE.GetLastError()); + } } @Test diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/GDI32UtilTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/GDI32UtilTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/GDI32UtilTest.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/GDI32UtilTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,56 @@ +/* Copyright (c) 2015 Michael Freeman, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ +package com.sun.jna.platform.win32; + +import java.awt.image.BufferedImage; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; +import org.junit.runner.JUnitCore; + +import com.sun.jna.platform.win32.WinDef.HWND; + +public class GDI32UtilTest extends AbstractWin32TestSupport { + + public static void main(String[] args) { + JUnitCore jUnitCore = new JUnitCore(); + jUnitCore.run(GDI32UtilTest.class); + } + + @Test + public void testGetScreenshot() { + HWND desktopWindow = User32.INSTANCE.GetDesktopWindow(); + assertNotNull("Failed to obtain desktop window handle", desktopWindow); + BufferedImage image = GDI32Util.getScreenshot(desktopWindow); + // Since this test involves taking a whole-desktop screenshot + // we can't be sure what the image will be exactly. + // We'll validate that the image is "good" + // 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(); + for (int x = 0; x < image.getWidth(); x++) { + for (int y = 0; y < image.getHeight(); y++) { + int pixel = image.getRGB(x, y); + if (!distinctPixels.contains(pixel)) { + distinctPixels.add(pixel); + } + if (distinctPixels.size() > 20) { + break; + } + } + } + assertTrue("Number of distinct pixels was not above 20.", distinctPixels.size() > 20); + } +} diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/Kernel32ConsoleTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/Kernel32ConsoleTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/Kernel32ConsoleTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/Kernel32ConsoleTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -49,9 +49,11 @@ @Test public void testGetConsoleWindow() { + // Only the call is done -- the prior test checked for not-null + // but running this test from netbeans IDE or console + // always resulted in NULL and this is a valid value + // (if there is no console attached) HWND hwnd=INSTANCE.GetConsoleWindow(); - // don't really care what the handle value is - just ensure that API can be called - assertNotNull("No console window handle", hwnd); } @Test diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/Kernel32EnvironmentVarsTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/Kernel32EnvironmentVarsTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/Kernel32EnvironmentVarsTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/Kernel32EnvironmentVarsTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -32,6 +32,11 @@ Map vars=Kernel32Util.getEnvironmentVariables(); for (Map.Entry entry : vars.entrySet()) { String name=entry.getKey(), expected=entry.getValue(); + if("".equals(name)) { + // Empty names are created by and env-entry with name "=C:..." + // as "=" is the split character, this fails here + continue; + } char[] data=new char[expected.length() + 1]; int size=Kernel32.INSTANCE.GetEnvironmentVariable(name, data, data.length); assertEquals("Mismatched retrieved length for " + name, data.length - 1 /* w/o the '\0' */, size); diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java 2017-03-14 19:31:03.000000000 +0000 @@ -12,6 +12,11 @@ */ package com.sun.jna.platform.win32; +import static com.sun.jna.platform.win32.WinioctlUtil.FSCTL_GET_COMPRESSION; +import static com.sun.jna.platform.win32.WinioctlUtil.FSCTL_GET_REPARSE_POINT; +import static com.sun.jna.platform.win32.WinioctlUtil.FSCTL_SET_COMPRESSION; +import static com.sun.jna.platform.win32.WinioctlUtil.FSCTL_SET_REPARSE_POINT; + import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; @@ -20,6 +25,10 @@ import java.io.IOException; import java.io.PrintWriter; import java.nio.ByteBuffer; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.attribute.FileTime; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; @@ -28,36 +37,59 @@ import java.util.List; import java.util.TimeZone; +import com.sun.jna.Function; +import com.sun.jna.Memory; import com.sun.jna.Native; +import com.sun.jna.NativeLibrary; import com.sun.jna.NativeMappedConverter; import com.sun.jna.Platform; import com.sun.jna.Pointer; import com.sun.jna.platform.win32.BaseTSD.SIZE_T; +import com.sun.jna.platform.win32.Ntifs.REPARSE_DATA_BUFFER; +import com.sun.jna.platform.win32.Ntifs.SymbolicLinkReparseBuffer; +import com.sun.jna.platform.win32.WinBase.FILETIME; +import com.sun.jna.platform.win32.WinBase.FILE_ATTRIBUTE_TAG_INFO; +import com.sun.jna.platform.win32.WinBase.FILE_BASIC_INFO; +import com.sun.jna.platform.win32.WinBase.FILE_COMPRESSION_INFO; +import com.sun.jna.platform.win32.WinBase.FILE_DISPOSITION_INFO; +import com.sun.jna.platform.win32.WinBase.FILE_ID_INFO; +import com.sun.jna.platform.win32.WinBase.FILE_STANDARD_INFO; import com.sun.jna.platform.win32.WinBase.MEMORYSTATUSEX; +import com.sun.jna.platform.win32.WinBase.SYSTEMTIME; import com.sun.jna.platform.win32.WinBase.SYSTEM_INFO; +import com.sun.jna.platform.win32.WinBase.WIN32_FIND_DATA; import com.sun.jna.platform.win32.WinDef.DWORD; +import com.sun.jna.platform.win32.WinDef.HMODULE; import com.sun.jna.platform.win32.WinDef.HWND; +import com.sun.jna.platform.win32.WinDef.USHORT; import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.platform.win32.WinNT.HANDLEByReference; import com.sun.jna.platform.win32.WinNT.MEMORY_BASIC_INFORMATION; import com.sun.jna.platform.win32.WinNT.OSVERSIONINFO; import com.sun.jna.platform.win32.WinNT.OSVERSIONINFOEX; import com.sun.jna.ptr.IntByReference; +import com.sun.jna.ptr.ShortByReference; import junit.framework.TestCase; public class Kernel32Test extends TestCase { public static void main(String[] args) { - OSVERSIONINFO lpVersionInfo = new OSVERSIONINFO(); - assertTrue(Kernel32.INSTANCE.GetVersionEx(lpVersionInfo)); - System.out.println("Operating system: " - + lpVersionInfo.dwMajorVersion.longValue() + "." + lpVersionInfo.dwMinorVersion.longValue() - + " (" + lpVersionInfo.dwBuildNumber + ")" - + " [" + Native.toString(lpVersionInfo.szCSDVersion) + "]"); + OSVERSIONINFO lpVersionInfo = new OSVERSIONINFO(); + assertTrue(Kernel32.INSTANCE.GetVersionEx(lpVersionInfo)); + System.out.println("Operating system: " + + lpVersionInfo.dwMajorVersion.longValue() + "." + lpVersionInfo.dwMinorVersion.longValue() + + " (" + lpVersionInfo.dwBuildNumber + ")" + + " [" + Native.toString(lpVersionInfo.szCSDVersion) + "]"); junit.textui.TestRunner.run(Kernel32Test.class); } + // see https://github.com/java-native-access/jna/issues/604 + public void testGetLastErrorNativeLibraryOverride() { + assertFalse("Unexpected success", Kernel32.INSTANCE.CloseHandle(null)); + assertEquals("Mismatched error code", WinError.ERROR_INVALID_HANDLE, Kernel32.INSTANCE.GetLastError()); + } + // see https://github.com/twall/jna/issues/482 public void testNoDuplicateMethodsNames() { Collection dupSet = AbstractWin32TestSupport.detectDuplicateMethods(Kernel32.class); @@ -205,289 +237,467 @@ } public void testGetComputerName() { - IntByReference lpnSize = new IntByReference(0); - assertFalse(Kernel32.INSTANCE.GetComputerName(null, lpnSize)); - assertEquals(WinError.ERROR_BUFFER_OVERFLOW, Kernel32.INSTANCE.GetLastError()); - char buffer[] = new char[WinBase.MAX_COMPUTERNAME_LENGTH + 1]; - lpnSize.setValue(buffer.length); - assertTrue(Kernel32.INSTANCE.GetComputerName(buffer, lpnSize)); + IntByReference lpnSize = new IntByReference(0); + assertFalse(Kernel32.INSTANCE.GetComputerName(null, lpnSize)); + assertEquals(WinError.ERROR_BUFFER_OVERFLOW, Kernel32.INSTANCE.GetLastError()); + char buffer[] = new char[WinBase.MAX_COMPUTERNAME_LENGTH + 1]; + lpnSize.setValue(buffer.length); + assertTrue(Kernel32.INSTANCE.GetComputerName(buffer, lpnSize)); } public void testGetComputerNameExSameAsGetComputerName() { - IntByReference lpnSize = new IntByReference(0); - char buffer[] = new char[WinBase.MAX_COMPUTERNAME_LENGTH + 1]; - lpnSize.setValue(buffer.length); - assertTrue("Failed to retrieve expected computer name", Kernel32.INSTANCE.GetComputerName(buffer, lpnSize)); + IntByReference lpnSize = new IntByReference(0); + char buffer[] = new char[WinBase.MAX_COMPUTERNAME_LENGTH + 1]; + lpnSize.setValue(buffer.length); + assertTrue("Failed to retrieve expected computer name", Kernel32.INSTANCE.GetComputerName(buffer, lpnSize)); String expected = Native.toString(buffer); // reset - lpnSize.setValue(buffer.length); + lpnSize.setValue(buffer.length); Arrays.fill(buffer, '\0'); - assertTrue("Failed to retrieve extended computer name", Kernel32.INSTANCE.GetComputerNameEx(WinBase.COMPUTER_NAME_FORMAT.ComputerNameNetBIOS, buffer, lpnSize)); + assertTrue("Failed to retrieve extended computer name", Kernel32.INSTANCE.GetComputerNameEx(WinBase.COMPUTER_NAME_FORMAT.ComputerNameNetBIOS, buffer, lpnSize)); String actual = Native.toString(buffer); assertEquals("Mismatched names", expected, actual); } public void testWaitForSingleObject() { - HANDLE handle = Kernel32.INSTANCE.CreateEvent(null, false, false, null); - - // handle runs into timeout since it is not triggered - // WAIT_TIMEOUT = 0x00000102 - assertEquals(WinError.WAIT_TIMEOUT, Kernel32.INSTANCE.WaitForSingleObject( - handle, 1000)); + HANDLE handle = Kernel32.INSTANCE.CreateEvent(null, false, false, null); + assertNotNull("Failed to create event: " + Kernel32.INSTANCE.GetLastError(), handle); - Kernel32.INSTANCE.CloseHandle(handle); - } + try { + // handle runs into timeout since it is not triggered + // WAIT_TIMEOUT = 0x00000102 + assertEquals(WinError.WAIT_TIMEOUT, Kernel32.INSTANCE.WaitForSingleObject(handle, 1000)); + } finally { + Kernel32Util.closeHandle(handle); + } + } public void testResetEvent() { - HANDLE handle = Kernel32.INSTANCE.CreateEvent(null, true, false, null); + HANDLE handle = Kernel32.INSTANCE.CreateEvent(null, true, false, null); + assertNotNull("Failed to create event: " + Kernel32.INSTANCE.GetLastError(), handle); - // set the event to the signaled state - Kernel32.INSTANCE.SetEvent(handle); - - // This should return successfully - assertEquals(WinBase.WAIT_OBJECT_0, Kernel32.INSTANCE.WaitForSingleObject( - handle, 1000)); - - // now reset it to not signaled - Kernel32.INSTANCE.ResetEvent(handle); - - // handle runs into timeout since it is not triggered - // WAIT_TIMEOUT = 0x00000102 - assertEquals(WinError.WAIT_TIMEOUT, Kernel32.INSTANCE.WaitForSingleObject( - handle, 1000)); + try { + // set the event to the signaled state + Kernel32.INSTANCE.SetEvent(handle); - Kernel32.INSTANCE.CloseHandle(handle); - } + // This should return successfully + assertEquals(WinBase.WAIT_OBJECT_0, Kernel32.INSTANCE.WaitForSingleObject( + handle, 1000)); + + // now reset it to not signaled + Kernel32.INSTANCE.ResetEvent(handle); + + // handle runs into timeout since it is not triggered + // WAIT_TIMEOUT = 0x00000102 + assertEquals(WinError.WAIT_TIMEOUT, Kernel32.INSTANCE.WaitForSingleObject(handle, 1000)); + } finally { + Kernel32Util.closeHandle(handle); + } + } public void testWaitForMultipleObjects(){ - HANDLE[] handles = new HANDLE[2]; - - handles[0] = Kernel32.INSTANCE.CreateEvent(null, false, false, null); - handles[1] = Kernel32.INSTANCE.CreateEvent(null, false, false, null); - - // handle runs into timeout since it is not triggered - // WAIT_TIMEOUT = 0x00000102 - assertEquals(WinError.WAIT_TIMEOUT, Kernel32.INSTANCE.WaitForMultipleObjects( - handles.length, handles, false, 1000)); - - Kernel32.INSTANCE.CloseHandle(handles[0]); - Kernel32.INSTANCE.CloseHandle(handles[1]); - - // invalid Handle - handles[0] = WinBase.INVALID_HANDLE_VALUE; - handles[1] = Kernel32.INSTANCE.CreateEvent(null, false, false, null); + HANDLE[] handles = new HANDLE[2]; + try { + for (int index = 0; index < handles.length; index++) { + HANDLE h = Kernel32.INSTANCE.CreateEvent(null, false, false, null); + assertNotNull("Failed to create event #" + index + ": " + Kernel32.INSTANCE.GetLastError(), h); + handles[index] = h; + } + // handle runs into timeout since it is not triggered + // WAIT_TIMEOUT = 0x00000102 + assertEquals(WinError.WAIT_TIMEOUT, Kernel32.INSTANCE.WaitForMultipleObjects( + handles.length, handles, false, 1000)); + } finally { + Kernel32Util.closeHandles(handles); + } - // returns WAIT_FAILED since handle is invalid - assertEquals(WinBase.WAIT_FAILED, Kernel32.INSTANCE.WaitForMultipleObjects( - handles.length, handles, false, 5000)); + // invalid Handle + handles[0] = WinBase.INVALID_HANDLE_VALUE; + handles[1] = Kernel32.INSTANCE.CreateEvent(null, false, false, null); + assertNotNull("Failed to create valid event: " + Kernel32.INSTANCE.GetLastError(), handles[1]); + try { + // returns WAIT_FAILED since handle is invalid + assertEquals(WinBase.WAIT_FAILED, Kernel32.INSTANCE.WaitForMultipleObjects( + handles.length, handles, false, 5000)); - Kernel32.INSTANCE.CloseHandle(handles[1]); + } finally { + Kernel32Util.closeHandle(handles[1]); + } } public void testGetCurrentThreadId() { - assertTrue(Kernel32.INSTANCE.GetCurrentThreadId() > 0); + assertTrue(Kernel32.INSTANCE.GetCurrentThreadId() > 0); } public void testGetCurrentThread() { - HANDLE h = Kernel32.INSTANCE.GetCurrentThread(); - assertNotNull(h); - assertFalse(h.equals(0)); - // CloseHandle does not need to be called for a thread handle - assertFalse(Kernel32.INSTANCE.CloseHandle(h)); - assertEquals(WinError.ERROR_INVALID_HANDLE, Kernel32.INSTANCE.GetLastError()); + HANDLE h = Kernel32.INSTANCE.GetCurrentThread(); + assertNotNull("No current thread handle", h); + assertFalse("Null current thread handle", h.equals(0)); + // Calling the CloseHandle function with this handle has no effect + Kernel32Util.closeHandle(h); } public void testOpenThread() { - HANDLE h = Kernel32.INSTANCE.OpenThread(WinNT.THREAD_ALL_ACCESS, false, - Kernel32.INSTANCE.GetCurrentThreadId()); - assertNotNull(h); - assertFalse(h.equals(0)); - assertTrue(Kernel32.INSTANCE.CloseHandle(h)); + HANDLE h = Kernel32.INSTANCE.OpenThread(WinNT.THREAD_ALL_ACCESS, false, + Kernel32.INSTANCE.GetCurrentThreadId()); + assertNotNull(h); + assertFalse(h.equals(0)); + Kernel32Util.closeHandle(h); } public void testGetCurrentProcessId() { - assertTrue(Kernel32.INSTANCE.GetCurrentProcessId() > 0); + assertTrue(Kernel32.INSTANCE.GetCurrentProcessId() > 0); } public void testGetCurrentProcess() { - HANDLE h = Kernel32.INSTANCE.GetCurrentProcess(); - assertNotNull(h); - assertFalse(h.equals(0)); - // CloseHandle does not need to be called for a process handle - assertFalse(Kernel32.INSTANCE.CloseHandle(h)); - assertEquals(WinError.ERROR_INVALID_HANDLE, Kernel32.INSTANCE.GetLastError()); + HANDLE h = Kernel32.INSTANCE.GetCurrentProcess(); + assertNotNull("No current process handle", h); + assertFalse("Null current process handle", h.equals(0)); + // Calling the CloseHandle function with a pseudo handle has no effect + Kernel32Util.closeHandle(h); } public void testOpenProcess() { - HANDLE h = Kernel32.INSTANCE.OpenProcess(0, false, - Kernel32.INSTANCE.GetCurrentProcessId()); - assertNull(h); - // opening your own process fails with access denied - assertEquals(WinError.ERROR_ACCESS_DENIED, Kernel32.INSTANCE.GetLastError()); + HANDLE h = Kernel32.INSTANCE.OpenProcess(0, false, + Kernel32.INSTANCE.GetCurrentProcessId()); + assertNull(h); + // opening your own process fails with access denied + assertEquals(WinError.ERROR_ACCESS_DENIED, Kernel32.INSTANCE.GetLastError()); + } + + public void testQueryFullProcessImageName() { + int pid = Kernel32.INSTANCE.GetCurrentProcessId(); + HANDLE h = Kernel32.INSTANCE.OpenProcess(WinNT.PROCESS_QUERY_INFORMATION, false, pid); + assertNotNull("Failed (" + Kernel32.INSTANCE.GetLastError() + ") to get process ID=" + pid + " handle", h); + + try { + char[] path = new char[WinDef.MAX_PATH]; + IntByReference lpdwSize = new IntByReference(path.length); + boolean b = Kernel32.INSTANCE.QueryFullProcessImageName(h, 0, path, lpdwSize); + assertTrue("Failed (" + Kernel32.INSTANCE.GetLastError() + ") to query process image name", b); + assertTrue("Failed to query process image name, empty path returned", lpdwSize.getValue() > 0); + } finally { + Kernel32Util.closeHandle(h); + } } public void testGetTempPath() { - char[] buffer = new char[WinDef.MAX_PATH]; - assertTrue(Kernel32.INSTANCE.GetTempPath(new DWORD(WinDef.MAX_PATH), buffer).intValue() > 0); + char[] buffer = new char[WinDef.MAX_PATH]; + assertTrue(Kernel32.INSTANCE.GetTempPath(new DWORD(WinDef.MAX_PATH), buffer).intValue() > 0); } - public void testGetTickCount() throws InterruptedException { - // Tick count rolls over every 49.7 days, so to safeguard from - // roll-over, we will get two time spans. At least one should - // yield a positive. - int tick1 = Kernel32.INSTANCE.GetTickCount(); - Thread.sleep(10); - int tick2 = Kernel32.INSTANCE.GetTickCount(); - Thread.sleep(10); - int tick3 = Kernel32.INSTANCE.GetTickCount(); + public void testGetTickCount() throws InterruptedException { + // Tick count rolls over every 49.7 days, so to safeguard from + // roll-over, we will get two time spans. At least one should + // yield a positive. + int tick1 = Kernel32.INSTANCE.GetTickCount(); + Thread.sleep(10); + int tick2 = Kernel32.INSTANCE.GetTickCount(); + Thread.sleep(10); + int tick3 = Kernel32.INSTANCE.GetTickCount(); - assertTrue(tick2 > tick1 || tick3 > tick2); - } + assertTrue(tick2 > tick1 || tick3 > tick2); + } + + public void testGetTickCount64() throws InterruptedException { + long tick1 = Kernel32.INSTANCE.GetTickCount64(); + Thread.sleep(100); + long tick2 = Kernel32.INSTANCE.GetTickCount64(); + + assertTrue(tick2 > tick1); + } public void testGetVersion() { - DWORD version = Kernel32.INSTANCE.GetVersion(); - assertTrue("Version high should be non-zero: 0x" + Integer.toHexString(version.getHigh().intValue()), version.getHigh().intValue() != 0); - assertTrue("Version low should be >= 0: 0x" + Integer.toHexString(version.getLow().intValue()), version.getLow().intValue() >= 0); + DWORD version = Kernel32.INSTANCE.GetVersion(); + assertTrue("Version high should be non-zero: 0x" + Integer.toHexString(version.getHigh().intValue()), version.getHigh().intValue() != 0); + assertTrue("Version low should be >= 0: 0x" + Integer.toHexString(version.getLow().intValue()), version.getLow().intValue() >= 0); } public void testGetVersionEx_OSVERSIONINFO() { - OSVERSIONINFO lpVersionInfo = new OSVERSIONINFO(); - assertEquals(lpVersionInfo.size(), lpVersionInfo.dwOSVersionInfoSize.longValue()); - assertTrue(Kernel32.INSTANCE.GetVersionEx(lpVersionInfo)); - assertTrue(lpVersionInfo.dwMajorVersion.longValue() > 0); - assertTrue(lpVersionInfo.dwMinorVersion.longValue() >= 0); - assertEquals(lpVersionInfo.size(), lpVersionInfo.dwOSVersionInfoSize.longValue()); - assertTrue(lpVersionInfo.dwPlatformId.longValue() > 0); - assertTrue(lpVersionInfo.dwBuildNumber.longValue() > 0); - assertTrue(Native.toString(lpVersionInfo.szCSDVersion).length() >= 0); + OSVERSIONINFO lpVersionInfo = new OSVERSIONINFO(); + assertEquals(lpVersionInfo.size(), lpVersionInfo.dwOSVersionInfoSize.longValue()); + assertTrue(Kernel32.INSTANCE.GetVersionEx(lpVersionInfo)); + assertTrue(lpVersionInfo.dwMajorVersion.longValue() > 0); + assertTrue(lpVersionInfo.dwMinorVersion.longValue() >= 0); + assertEquals(lpVersionInfo.size(), lpVersionInfo.dwOSVersionInfoSize.longValue()); + assertTrue(lpVersionInfo.dwPlatformId.longValue() > 0); + assertTrue(lpVersionInfo.dwBuildNumber.longValue() > 0); + assertTrue(Native.toString(lpVersionInfo.szCSDVersion).length() >= 0); } public void testGetVersionEx_OSVERSIONINFOEX() { - OSVERSIONINFOEX lpVersionInfo = new OSVERSIONINFOEX(); - assertEquals(lpVersionInfo.size(), lpVersionInfo.dwOSVersionInfoSize.longValue()); - assertTrue(Kernel32.INSTANCE.GetVersionEx(lpVersionInfo)); - assertTrue(lpVersionInfo.dwMajorVersion.longValue() > 0); - assertTrue(lpVersionInfo.dwMinorVersion.longValue() >= 0); - assertEquals(lpVersionInfo.size(), lpVersionInfo.dwOSVersionInfoSize.longValue()); - assertTrue(lpVersionInfo.dwPlatformId.longValue() > 0); - assertTrue(lpVersionInfo.dwBuildNumber.longValue() > 0); - assertTrue(Native.toString(lpVersionInfo.szCSDVersion).length() >= 0); - assertTrue(lpVersionInfo.wProductType >= 0); + OSVERSIONINFOEX lpVersionInfo = new OSVERSIONINFOEX(); + assertEquals(lpVersionInfo.size(), lpVersionInfo.dwOSVersionInfoSize.longValue()); + assertTrue(Kernel32.INSTANCE.GetVersionEx(lpVersionInfo)); + assertTrue(lpVersionInfo.getMajor() > 0); + assertTrue(lpVersionInfo.getMinor() >= 0); + assertEquals(lpVersionInfo.size(), lpVersionInfo.dwOSVersionInfoSize.longValue()); + assertTrue(lpVersionInfo.getPlatformId() > 0); + assertTrue(lpVersionInfo.getBuildNumber() > 0); + assertTrue(lpVersionInfo.getServicePack().length() >= 0); + assertTrue(lpVersionInfo.getProductType() >= 0); } public void testGetSystemInfo() { - SYSTEM_INFO lpSystemInfo = new SYSTEM_INFO(); - Kernel32.INSTANCE.GetSystemInfo(lpSystemInfo); - assertTrue(lpSystemInfo.dwNumberOfProcessors.intValue() > 0); + SYSTEM_INFO lpSystemInfo = new SYSTEM_INFO(); + Kernel32.INSTANCE.GetSystemInfo(lpSystemInfo); + assertTrue(lpSystemInfo.dwNumberOfProcessors.intValue() > 0); + } + + public void testGetSystemTimes() { + Kernel32 kernel = Kernel32.INSTANCE; + FILETIME lpIdleTime = new FILETIME(); + FILETIME lpKernelTime = new FILETIME(); + FILETIME lpUserTime = new FILETIME(); + boolean succ = kernel.GetSystemTimes(lpIdleTime, lpKernelTime, lpUserTime); + assertTrue(succ); + long idleTime = lpIdleTime.toDWordLong().longValue(); + long kernelTime = lpKernelTime.toDWordLong().longValue(); + long userTime = lpUserTime.toDWordLong().longValue(); + // All should be >= 0. kernel includes idle. + assertTrue(idleTime >= 0); + assertTrue(kernelTime >= idleTime); + assertTrue(userTime >= 0); } public void testIsWow64Process() { - try { - IntByReference isWow64 = new IntByReference(42); - HANDLE hProcess = Kernel32.INSTANCE.GetCurrentProcess(); - assertTrue(Kernel32.INSTANCE.IsWow64Process(hProcess, isWow64)); - assertTrue(0 == isWow64.getValue() || 1 == isWow64.getValue()); - } catch (UnsatisfiedLinkError e) { - // IsWow64Process is not available on this OS - } + try { + IntByReference isWow64 = new IntByReference(42); + HANDLE hProcess = Kernel32.INSTANCE.GetCurrentProcess(); + assertTrue(Kernel32.INSTANCE.IsWow64Process(hProcess, isWow64)); + assertTrue(0 == isWow64.getValue() || 1 == isWow64.getValue()); + } catch (UnsatisfiedLinkError e) { + // IsWow64Process is not available on this OS + } } public void testGetNativeSystemInfo() { - try { - SYSTEM_INFO lpSystemInfo = new SYSTEM_INFO(); - Kernel32.INSTANCE.GetNativeSystemInfo(lpSystemInfo); - assertTrue(lpSystemInfo.dwNumberOfProcessors.intValue() > 0); - } catch (UnsatisfiedLinkError e) { - // only available under WOW64 - } + try { + SYSTEM_INFO lpSystemInfo = new SYSTEM_INFO(); + Kernel32.INSTANCE.GetNativeSystemInfo(lpSystemInfo); + assertTrue(lpSystemInfo.dwNumberOfProcessors.intValue() > 0); + } catch (UnsatisfiedLinkError e) { + // only available under WOW64 + } } public void testGlobalMemoryStatusEx() { - MEMORYSTATUSEX lpBuffer = new MEMORYSTATUSEX(); - assertTrue(Kernel32.INSTANCE.GlobalMemoryStatusEx(lpBuffer)); - assertTrue(lpBuffer.ullTotalPhys.longValue() > 0); - assertTrue(lpBuffer.dwMemoryLoad.intValue() >= 0 && lpBuffer.dwMemoryLoad.intValue() <= 100); - assertEquals(0, lpBuffer.ullAvailExtendedVirtual.intValue()); + MEMORYSTATUSEX lpBuffer = new MEMORYSTATUSEX(); + assertTrue(Kernel32.INSTANCE.GlobalMemoryStatusEx(lpBuffer)); + assertTrue(lpBuffer.ullTotalPhys.longValue() > 0); + assertTrue(lpBuffer.dwMemoryLoad.intValue() >= 0 && lpBuffer.dwMemoryLoad.intValue() <= 100); + assertEquals(0, lpBuffer.ullAvailExtendedVirtual.intValue()); } public void testDeleteFile() { - String filename = Kernel32Util.getTempPath() + "\\FileDoesNotExist.jna"; - assertFalse(Kernel32.INSTANCE.DeleteFile(filename)); - assertEquals(WinError.ERROR_FILE_NOT_FOUND, Kernel32.INSTANCE.GetLastError()); + String filename = Kernel32Util.getTempPath() + "\\FileDoesNotExist.jna"; + assertFalse(Kernel32.INSTANCE.DeleteFile(filename)); + assertEquals(WinError.ERROR_FILE_NOT_FOUND, Kernel32.INSTANCE.GetLastError()); } public void testReadFile() throws IOException { - String expected = "jna - testReadFile"; - File tmp = File.createTempFile("testReadFile", "jna"); - tmp.deleteOnExit(); - - FileWriter fw = new FileWriter(tmp); - try { - fw.append(expected); - } finally { - fw.close(); - } - - HANDLE hFile = Kernel32.INSTANCE.CreateFile(tmp.getAbsolutePath(), WinNT.GENERIC_READ, WinNT.FILE_SHARE_READ, - new WinBase.SECURITY_ATTRIBUTES(), WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); - assertFalse("Failed to create file handle: " + tmp, WinBase.INVALID_HANDLE_VALUE.equals(hFile)); + String expected = "jna - testReadFile"; + File tmp = File.createTempFile("testReadFile", "jna"); + tmp.deleteOnExit(); + + FileWriter fw = new FileWriter(tmp); + try { + fw.append(expected); + } finally { + fw.close(); + } + + HANDLE hFile = Kernel32.INSTANCE.CreateFile(tmp.getAbsolutePath(), WinNT.GENERIC_READ, WinNT.FILE_SHARE_READ, + new WinBase.SECURITY_ATTRIBUTES(), WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); + assertFalse("Failed to create file handle: " + tmp, WinBase.INVALID_HANDLE_VALUE.equals(hFile)); - try { + try { byte[] readBuffer=new byte[expected.length() + Byte.MAX_VALUE]; - IntByReference lpNumberOfBytesRead = new IntByReference(0); - assertTrue("Failed to read from file", Kernel32.INSTANCE.ReadFile(hFile, readBuffer, readBuffer.length, lpNumberOfBytesRead, null)); + IntByReference lpNumberOfBytesRead = new IntByReference(0); + assertTrue("Failed to read from file", Kernel32.INSTANCE.ReadFile(hFile, readBuffer, readBuffer.length, lpNumberOfBytesRead, null)); - int read = lpNumberOfBytesRead.getValue(); - assertEquals("Mismatched read size", expected.length(), read); + int read = lpNumberOfBytesRead.getValue(); + assertEquals("Mismatched read size", expected.length(), read); - assertEquals("Mismatched read content", expected, new String(readBuffer, 0, read)); - } finally { - assertTrue("Failed to close file", Kernel32.INSTANCE.CloseHandle(hFile)); - } + assertEquals("Mismatched read content", expected, new String(readBuffer, 0, read)); + } finally { + Kernel32Util.closeHandle(hFile); + } } public void testSetHandleInformation() throws IOException { - File tmp = File.createTempFile("testSetHandleInformation", "jna"); - tmp.deleteOnExit(); - - HANDLE hFile = Kernel32.INSTANCE.CreateFile(tmp.getAbsolutePath(), WinNT.GENERIC_READ, WinNT.FILE_SHARE_READ, - new WinBase.SECURITY_ATTRIBUTES(), WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); - assertFalse(hFile == WinBase.INVALID_HANDLE_VALUE); + File tmp = File.createTempFile("testSetHandleInformation", "jna"); + tmp.deleteOnExit(); - assertTrue(Kernel32.INSTANCE.SetHandleInformation(hFile, WinBase.HANDLE_FLAG_PROTECT_FROM_CLOSE, 0)); - assertTrue(Kernel32.INSTANCE.CloseHandle(hFile)); + HANDLE hFile = Kernel32.INSTANCE.CreateFile(tmp.getAbsolutePath(), WinNT.GENERIC_READ, WinNT.FILE_SHARE_READ, + new WinBase.SECURITY_ATTRIBUTES(), WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); + assertFalse(WinBase.INVALID_HANDLE_VALUE.equals(hFile)); + try { + assertTrue(Kernel32.INSTANCE.SetHandleInformation(hFile, WinBase.HANDLE_FLAG_PROTECT_FROM_CLOSE, 0)); + } finally { + Kernel32Util.closeHandle(hFile); + } } public void testCreatePipe() { - HANDLEByReference hReadPipe = new HANDLEByReference(); - HANDLEByReference hWritePipe = new HANDLEByReference(); - - assertTrue(Kernel32.INSTANCE.CreatePipe(hReadPipe, hWritePipe, null, 0)); - assertTrue(Kernel32.INSTANCE.CloseHandle(hReadPipe.getValue())); - assertTrue(Kernel32.INSTANCE.CloseHandle(hWritePipe.getValue())); + HANDLEByReference hReadPipe = new HANDLEByReference(); + HANDLEByReference hWritePipe = new HANDLEByReference(); + try { + assertTrue(Kernel32.INSTANCE.CreatePipe(hReadPipe, hWritePipe, null, 0)); + } finally { + Kernel32Util.closeHandleRefs(hReadPipe, hWritePipe); + } } public void testGetExitCodeProcess() { - IntByReference lpExitCode = new IntByReference(0); - assertTrue(Kernel32.INSTANCE.GetExitCodeProcess(Kernel32.INSTANCE.GetCurrentProcess(), lpExitCode)); - assertEquals(WinBase.STILL_ACTIVE, lpExitCode.getValue()); + IntByReference lpExitCode = new IntByReference(0); + assertTrue(Kernel32.INSTANCE.GetExitCodeProcess(Kernel32.INSTANCE.GetCurrentProcess(), lpExitCode)); + assertEquals(WinBase.STILL_ACTIVE, lpExitCode.getValue()); } public void testTerminateProcess() throws IOException { - File tmp = File.createTempFile("testTerminateProcess", "jna"); - tmp.deleteOnExit(); - HANDLE hFile = Kernel32.INSTANCE.CreateFile(tmp.getAbsolutePath(), WinNT.GENERIC_READ, WinNT.FILE_SHARE_READ, - new WinBase.SECURITY_ATTRIBUTES(), WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); - - assertFalse(Kernel32.INSTANCE.TerminateProcess(hFile, 1)); - assertEquals(WinError.ERROR_INVALID_HANDLE, Kernel32.INSTANCE.GetLastError()); - assertTrue(Kernel32.INSTANCE.CloseHandle(hFile)); + File tmp = File.createTempFile("testTerminateProcess", "jna"); + tmp.deleteOnExit(); + HANDLE hFile = Kernel32.INSTANCE.CreateFile(tmp.getAbsolutePath(), WinNT.GENERIC_READ, WinNT.FILE_SHARE_READ, + new WinBase.SECURITY_ATTRIBUTES(), WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); + assertFalse(WinBase.INVALID_HANDLE_VALUE.equals(hFile)); + try { + assertFalse(Kernel32.INSTANCE.TerminateProcess(hFile, 1)); + assertEquals(WinError.ERROR_INVALID_HANDLE, Kernel32.INSTANCE.GetLastError()); + } finally { + Kernel32Util.closeHandle(hFile); + } } public void testGetFileAttributes() { - assertTrue(WinBase.INVALID_FILE_ATTRIBUTES != Kernel32.INSTANCE.GetFileAttributes(".")); + assertTrue(WinBase.INVALID_FILE_ATTRIBUTES != Kernel32.INSTANCE.GetFileAttributes(".")); + } + + public void testDeviceIoControlFsctlCompression() throws IOException { + File tmp = File.createTempFile("testDeviceIoControlFsctlCompression", "jna"); + tmp.deleteOnExit(); + + HANDLE hFile = Kernel32.INSTANCE.CreateFile(tmp.getAbsolutePath(), WinNT.GENERIC_ALL, WinNT.FILE_SHARE_READ, + new WinBase.SECURITY_ATTRIBUTES(), WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); + assertFalse(WinBase.INVALID_HANDLE_VALUE.equals(hFile)); + + try { + ShortByReference lpBuffer = new ShortByReference(); + IntByReference lpBytes = new IntByReference(); + + if (false == Kernel32.INSTANCE.DeviceIoControl(hFile, + FSCTL_GET_COMPRESSION, + null, + 0, + lpBuffer.getPointer(), + USHORT.SIZE, + lpBytes, + null)) { + fail("DeviceIoControl failed with " + Kernel32.INSTANCE.GetLastError()); + } + assertEquals(WinNT.COMPRESSION_FORMAT_NONE, lpBuffer.getValue()); + assertEquals(USHORT.SIZE, lpBytes.getValue()); + + lpBuffer = new ShortByReference((short)WinNT.COMPRESSION_FORMAT_LZNT1); + + if (false == Kernel32.INSTANCE.DeviceIoControl(hFile, + FSCTL_SET_COMPRESSION, + lpBuffer.getPointer(), + USHORT.SIZE, + null, + 0, + lpBytes, + null)) { + fail("DeviceIoControl failed with " + Kernel32.INSTANCE.GetLastError()); + } + + if (false == Kernel32.INSTANCE.DeviceIoControl(hFile, + FSCTL_GET_COMPRESSION, + null, + 0, + lpBuffer.getPointer(), + USHORT.SIZE, + lpBytes, + null)) { + fail("DeviceIoControl failed with " + Kernel32.INSTANCE.GetLastError()); + } + assertEquals(WinNT.COMPRESSION_FORMAT_LZNT1, lpBuffer.getValue()); + assertEquals(USHORT.SIZE, lpBytes.getValue()); + + } finally { + Kernel32Util.closeHandle(hFile); + } + } + + /** + * NOTE: Due to process elevation, this test must be run as administrator + * @throws IOException + */ + public void testDeviceIoControlFsctlReparse() throws IOException { + Path folder = Files.createTempDirectory("testDeviceIoControlFsctlReparse_FOLDER"); + Path link = Files.createTempDirectory("testDeviceIoControlFsctlReparse_LINK"); + File delFolder = folder.toFile(); + delFolder.deleteOnExit(); + File delLink = link.toFile(); + delLink.deleteOnExit(); + + // Required for FSCTL_SET_REPARSE_POINT + Advapi32Util.Privilege restore = new Advapi32Util.Privilege(WinNT.SE_RESTORE_NAME); + try { + restore.enable(); + HANDLE hFile = Kernel32.INSTANCE.CreateFile(link.toAbsolutePath().toString(), + WinNT.GENERIC_READ | WinNT.FILE_WRITE_ATTRIBUTES | WinNT.FILE_WRITE_EA, + WinNT.FILE_SHARE_READ | WinNT.FILE_SHARE_WRITE | WinNT.FILE_SHARE_DELETE, + new WinBase.SECURITY_ATTRIBUTES(), + WinNT.OPEN_EXISTING, + WinNT.FILE_ATTRIBUTE_DIRECTORY | WinNT.FILE_FLAG_BACKUP_SEMANTICS | WinNT.FILE_FLAG_OPEN_REPARSE_POINT, + null); + + if (WinBase.INVALID_HANDLE_VALUE.equals(hFile)) { + fail("CreateFile failed with " + Kernel32.INSTANCE.GetLastError()); + } + + try { + SymbolicLinkReparseBuffer symLinkReparseBuffer = new SymbolicLinkReparseBuffer(folder.getFileName().toString(), + folder.getFileName().toString(), + Ntifs.SYMLINK_FLAG_RELATIVE); + + REPARSE_DATA_BUFFER lpBuffer = new REPARSE_DATA_BUFFER(WinNT.IO_REPARSE_TAG_SYMLINK, (short) 0, symLinkReparseBuffer); + + assertTrue(Kernel32.INSTANCE.DeviceIoControl(hFile, + FSCTL_SET_REPARSE_POINT, + lpBuffer.getPointer(), + lpBuffer.getSize(), + null, + 0, + null, + null)); + + Memory p = new Memory(REPARSE_DATA_BUFFER.sizeOf()); + IntByReference lpBytes = new IntByReference(); + assertTrue(Kernel32.INSTANCE.DeviceIoControl(hFile, + FSCTL_GET_REPARSE_POINT, + null, + 0, + p, + (int) p.size(), + lpBytes, + null)); + // Is a reparse point + lpBuffer = new REPARSE_DATA_BUFFER(p); + assertTrue(lpBytes.getValue() > 0); + assertTrue(lpBuffer.ReparseTag == WinNT.IO_REPARSE_TAG_SYMLINK); + assertEquals(folder.getFileName().toString(), lpBuffer.u.symLinkReparseBuffer.getPrintName()); + assertEquals(folder.getFileName().toString(), lpBuffer.u.symLinkReparseBuffer.getSubstituteName()); + } finally { + Kernel32Util.closeHandle(hFile); + } + } + finally { + restore.close(); + } } public void testCopyFile() throws IOException { @@ -542,28 +752,261 @@ assertTrue(processInformation.dwProcessId.longValue() > 0); } - public void testGetSetFileTime() throws IOException { - File tmp = File.createTempFile("testGetSetFileTime", "jna"); + public void testFindFirstFile() throws IOException { + Path tmpDir = Files.createTempDirectory("testFindFirstFile"); + File tmpFile = new File(Files.createTempFile(tmpDir, "testFindFirstFile", ".jna").toString()); + + Memory p = new Memory(WIN32_FIND_DATA.sizeOf()); + HANDLE hFile = Kernel32.INSTANCE.FindFirstFile(tmpDir.toAbsolutePath().toString() + "\\*", p); + assertFalse(WinBase.INVALID_HANDLE_VALUE.equals(hFile)); + + try { + + // 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()); + 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()); + 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()); + assertTrue(actualFileName.contentEquals(tmpFile.getName())); + + // No more files in directory + assertFalse(Kernel32.INSTANCE.FindNextFile(hFile, p)); + assertEquals(WinNT.ERROR_NO_MORE_FILES, Kernel32.INSTANCE.GetLastError()); + } + finally { + Kernel32.INSTANCE.FindClose(hFile); + tmpFile.delete(); + Files.delete(tmpDir); + } + } + + public void testFindFirstFileExFindExInfoStandard() throws IOException { + Path tmpDir = Files.createTempDirectory("testFindFirstFileExFindExInfoStandard"); + File tmpFile = new File(Files.createTempFile(tmpDir, "testFindFirstFileExFindExInfoStandard", ".jna").toString()); + + Memory p = new Memory(WIN32_FIND_DATA.sizeOf()); + HANDLE hFile = Kernel32.INSTANCE.FindFirstFileEx(tmpDir.toAbsolutePath().toString() + "\\*", + WinBase.FindExInfoStandard, + p, + WinBase.FindExSearchNameMatch, + null, + new DWORD(0)); + assertFalse(WinBase.INVALID_HANDLE_VALUE.equals(hFile)); + + try { + + // 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()); + 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()); + 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()); + assertTrue(actualFileName.contentEquals(tmpFile.getName())); + + // No more files in directory + assertFalse(Kernel32.INSTANCE.FindNextFile(hFile, p)); + assertEquals(WinNT.ERROR_NO_MORE_FILES, Kernel32.INSTANCE.GetLastError()); + } + finally { + Kernel32.INSTANCE.FindClose(hFile); + tmpFile.delete(); + Files.delete(tmpDir); + } + } + + public void testFindFirstFileExFindExInfoBasic() throws IOException { + Path tmpDir = Files.createTempDirectory("testFindFirstFileExFindExInfoBasic"); + File tmpFile = new File(Files.createTempFile(tmpDir, "testFindFirstFileExFindExInfoBasic", ".jna").toString()); + + Memory p = new Memory(WIN32_FIND_DATA.sizeOf()); + // Add the file name to the search to get just that one entry + HANDLE hFile = Kernel32.INSTANCE.FindFirstFileEx(tmpDir.toAbsolutePath().toString() + "\\" + tmpFile.getName(), + WinBase.FindExInfoBasic, + p, + WinBase.FindExSearchNameMatch, + null, + new DWORD(0)); + assertFalse(WinBase.INVALID_HANDLE_VALUE.equals(hFile)); + + 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()); + assertTrue(actualFileName.contentEquals(tmpFile.getName())); + + // FindExInfoBasic does not return the short name, so confirm that its empty + String alternateFileName = fd.getAlternateFileName(); + assertTrue(alternateFileName.isEmpty()); + + // No more files in directory + assertFalse(Kernel32.INSTANCE.FindNextFile(hFile, p)); + assertEquals(WinNT.ERROR_NO_MORE_FILES, Kernel32.INSTANCE.GetLastError()); + } + finally { + Kernel32.INSTANCE.FindClose(hFile); + tmpFile.delete(); + Files.delete(tmpDir); + } + } + + public void testGetFileInformationByHandleEx() throws IOException { + File tmp = File.createTempFile("testGetFileInformationByHandleEx", "jna"); tmp.deleteOnExit(); HANDLE hFile = Kernel32.INSTANCE.CreateFile(tmp.getAbsolutePath(), WinNT.GENERIC_WRITE, WinNT.FILE_SHARE_WRITE, - new WinBase.SECURITY_ATTRIBUTES(), WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); - assertFalse(hFile == WinBase.INVALID_HANDLE_VALUE); + new WinBase.SECURITY_ATTRIBUTES(), WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); + assertFalse(WinBase.INVALID_HANDLE_VALUE.equals(hFile)); + + try { + + Memory p = new Memory(FILE_BASIC_INFO.sizeOf()); + if (false == Kernel32.INSTANCE.GetFileInformationByHandleEx(hFile, WinBase.FileBasicInfo, p, new DWORD(p.size()))) { + fail("GetFileInformationByHandleEx failed with " + Kernel32.INSTANCE.GetLastError()); + } + FILE_BASIC_INFO fbi = new FILE_BASIC_INFO(p); + // New file has non-zero creation time + assertTrue(0 != fbi.CreationTime.getValue()); + + p = new Memory(FILE_STANDARD_INFO.sizeOf()); + if (false == Kernel32.INSTANCE.GetFileInformationByHandleEx(hFile, WinBase.FileStandardInfo, p, new DWORD(p.size()))) { + fail("GetFileInformationByHandleEx failed with " + Kernel32.INSTANCE.GetLastError()); + } + FILE_STANDARD_INFO fsi = new FILE_STANDARD_INFO(p); + // New file has 1 link + assertEquals(1, fsi.NumberOfLinks); + + p = new Memory(FILE_COMPRESSION_INFO.sizeOf()); + if (false == Kernel32.INSTANCE.GetFileInformationByHandleEx(hFile, WinBase.FileCompressionInfo, p, new DWORD(p.size()))) { + fail("GetFileInformationByHandleEx failed with " + Kernel32.INSTANCE.GetLastError()); + } + FILE_COMPRESSION_INFO fci = new FILE_COMPRESSION_INFO(p); + // Uncompressed file should be zero + assertEquals(0, fci.CompressionFormat); + + p = new Memory(FILE_ATTRIBUTE_TAG_INFO.sizeOf()); + if (false == Kernel32.INSTANCE.GetFileInformationByHandleEx(hFile, WinBase.FileAttributeTagInfo, p, new DWORD(p.size()))) { + fail("GetFileInformationByHandleEx failed with " + Kernel32.INSTANCE.GetLastError()); + } + FILE_ATTRIBUTE_TAG_INFO fati = new FILE_ATTRIBUTE_TAG_INFO(p); + // New files have the archive bit + assertEquals(WinNT.FILE_ATTRIBUTE_ARCHIVE, fati.FileAttributes); + + p = new Memory(FILE_ID_INFO.sizeOf()); + if (false == Kernel32.INSTANCE.GetFileInformationByHandleEx(hFile, WinBase.FileIdInfo, p, new DWORD(p.size()))) { + fail("GetFileInformationByHandleEx failed with " + Kernel32.INSTANCE.GetLastError()); + } + FILE_ID_INFO fii = new FILE_ID_INFO(p); + // Volume serial number should be non-zero + assertFalse(fii.VolumeSerialNumber == 0); + } finally { + Kernel32.INSTANCE.CloseHandle(hFile); + } + } + + public void testSetFileInformationByHandleFileBasicInfo() throws IOException, InterruptedException { + File tmp = File.createTempFile("testSetFileInformationByHandleFileBasicInfo", "jna"); + tmp.deleteOnExit(); + + HANDLE hFile = Kernel32.INSTANCE.CreateFile(tmp.getAbsolutePath(), + WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, + WinNT.FILE_SHARE_READ | WinNT.FILE_SHARE_WRITE, + new WinBase.SECURITY_ATTRIBUTES(), + WinNT.OPEN_EXISTING, + WinNT.FILE_ATTRIBUTE_NORMAL, + null); + + assertFalse(WinBase.INVALID_HANDLE_VALUE.equals(hFile)); + + try { + Memory p = new Memory(FILE_BASIC_INFO.sizeOf()); + if (false == Kernel32.INSTANCE.GetFileInformationByHandleEx(hFile, WinBase.FileBasicInfo, p, new DWORD(p.size()))) + fail("GetFileInformationByHandleEx failed with " + Kernel32.INSTANCE.GetLastError()); + + FILE_BASIC_INFO fbi = new FILE_BASIC_INFO(p); + // Add TEMP attribute + fbi.FileAttributes = fbi.FileAttributes | WinNT.FILE_ATTRIBUTE_TEMPORARY; + fbi.ChangeTime = new WinNT.LARGE_INTEGER(0); + fbi.CreationTime = new WinNT.LARGE_INTEGER(0); + fbi.LastAccessTime = new WinNT.LARGE_INTEGER(0); + fbi.LastWriteTime = new WinNT.LARGE_INTEGER(0); + fbi.write(); + + if (false == Kernel32.INSTANCE.SetFileInformationByHandle(hFile, WinBase.FileBasicInfo, fbi.getPointer(), new DWORD(FILE_BASIC_INFO.sizeOf()))) + fail("GetFileInformationByHandleEx failed with " + Kernel32.INSTANCE.GetLastError()); - WinBase.FILETIME.ByReference creationTime = new WinBase.FILETIME.ByReference(); - WinBase.FILETIME.ByReference accessTime = new WinBase.FILETIME.ByReference(); - WinBase.FILETIME.ByReference modifiedTime = new WinBase.FILETIME.ByReference(); - Kernel32.INSTANCE.GetFileTime(hFile, creationTime, accessTime, modifiedTime); + if (false == Kernel32.INSTANCE.GetFileInformationByHandleEx(hFile, WinBase.FileBasicInfo, p, new DWORD(p.size()))) + fail("GetFileInformationByHandleEx failed with " + Kernel32.INSTANCE.GetLastError()); - assertEquals(creationTime.toDate().getYear(), new Date().getYear()); - assertEquals(accessTime.toDate().getYear(), new Date().getYear()); - assertEquals(modifiedTime.toDate().getYear(), new Date().getYear()); + fbi = new FILE_BASIC_INFO(p); + assertTrue((fbi.FileAttributes & WinNT.FILE_ATTRIBUTE_TEMPORARY) != 0); + } + finally { + Kernel32.INSTANCE.CloseHandle(hFile); + } + } + + public void testSetFileInformationByHandleFileDispositionInfo() throws IOException, InterruptedException { + File tmp = File.createTempFile("testSetFileInformationByHandleFileDispositionInfo", "jna"); + + HANDLE hFile = Kernel32.INSTANCE.CreateFile(tmp.getAbsolutePath(), WinNT.GENERIC_WRITE | WinNT.DELETE, WinNT.FILE_SHARE_WRITE, + new WinBase.SECURITY_ATTRIBUTES(), WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); + + assertFalse(WinBase.INVALID_HANDLE_VALUE.equals(hFile)); + + try { + FILE_DISPOSITION_INFO fdi = new FILE_DISPOSITION_INFO(true); + if (false == Kernel32.INSTANCE.SetFileInformationByHandle(hFile, WinBase.FileDispositionInfo, fdi.getPointer(), new DWORD(FILE_DISPOSITION_INFO.sizeOf()))) + fail("SetFileInformationByHandle failed with " + Kernel32.INSTANCE.GetLastError()); - Kernel32.INSTANCE.SetFileTime(hFile, null, null, new WinBase.FILETIME(new Date(2010, 1, 1))); + } finally { + Kernel32.INSTANCE.CloseHandle(hFile); + } + + assertFalse(Files.exists(Paths.get(tmp.getAbsolutePath()))); + } + + public void testGetSetFileTime() throws IOException { + File tmp = File.createTempFile("testGetSetFileTime", "jna"); + tmp.deleteOnExit(); - assertTrue(Kernel32.INSTANCE.CloseHandle(hFile)); + HANDLE hFile = Kernel32.INSTANCE.CreateFile(tmp.getAbsolutePath(), WinNT.GENERIC_WRITE, WinNT.FILE_SHARE_WRITE, + new WinBase.SECURITY_ATTRIBUTES(), WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); + assertFalse(WinBase.INVALID_HANDLE_VALUE.equals(hFile)); + try { + WinBase.FILETIME.ByReference creationTime = new WinBase.FILETIME.ByReference(); + WinBase.FILETIME.ByReference accessTime = new WinBase.FILETIME.ByReference(); + WinBase.FILETIME.ByReference modifiedTime = new WinBase.FILETIME.ByReference(); + Kernel32.INSTANCE.GetFileTime(hFile, creationTime, accessTime, modifiedTime); + + assertEquals(creationTime.toDate().getYear(), new Date().getYear()); + assertEquals(accessTime.toDate().getYear(), new Date().getYear()); + assertEquals(modifiedTime.toDate().getYear(), new Date().getYear()); - assertEquals(2010, new Date(tmp.lastModified()).getYear()); + Kernel32.INSTANCE.SetFileTime(hFile, null, null, new WinBase.FILETIME(new Date(2010, 1, 1))); + assertEquals(2010, new Date(tmp.lastModified()).getYear()); + } finally { + Kernel32Util.closeHandle(hFile); + } } public void testSetFileAttributes() throws IOException { @@ -577,23 +1020,24 @@ } public void testGetProcessList() throws IOException { - WinNT.HANDLE processEnumHandle = Kernel32.INSTANCE.CreateToolhelp32Snapshot(Tlhelp32.TH32CS_SNAPALL, new WinDef.DWORD(0)); + HANDLE processEnumHandle = Kernel32.INSTANCE.CreateToolhelp32Snapshot(Tlhelp32.TH32CS_SNAPALL, new WinDef.DWORD(0)); assertFalse(WinBase.INVALID_HANDLE_VALUE.equals(processEnumHandle)); + try { + Tlhelp32.PROCESSENTRY32.ByReference processEntry = new Tlhelp32.PROCESSENTRY32.ByReference(); - Tlhelp32.PROCESSENTRY32.ByReference processEntry = new Tlhelp32.PROCESSENTRY32.ByReference(); + assertTrue(Kernel32.INSTANCE.Process32First(processEnumHandle, processEntry)); - assertTrue(Kernel32.INSTANCE.Process32First(processEnumHandle, processEntry)); + List processIdList = new ArrayList(); + processIdList.add(processEntry.th32ProcessID.longValue()); - List processIdList = new ArrayList(); - processIdList.add(processEntry.th32ProcessID.longValue()); + while (Kernel32.INSTANCE.Process32Next(processEnumHandle, processEntry)) { + processIdList.add(processEntry.th32ProcessID.longValue()); + } - while (Kernel32.INSTANCE.Process32Next(processEnumHandle, processEntry)) - { - processIdList.add(processEntry.th32ProcessID.longValue()); + assertTrue(processIdList.size() > 4); + } finally { + Kernel32Util.closeHandle(processEnumHandle); } - - assertTrue(Kernel32.INSTANCE.CloseHandle(processEnumHandle)); - assertTrue(processIdList.size() > 4); } public final void testGetPrivateProfileInt() throws IOException { @@ -709,56 +1153,122 @@ reader.close(); } + /** + * Test both SystemTimeToFileTime and FileTimeToSystemTime + * @throws IOException + */ + public final void testSystemTimeToFileTimeAndFileTimeToSystemTime() throws IOException { + + WinBase.SYSTEMTIME systemTime = new WinBase.SYSTEMTIME(); + Kernel32.INSTANCE.GetSystemTime(systemTime); + WinBase.FILETIME fileTime = new WinBase.FILETIME(); + + if (false == Kernel32.INSTANCE.SystemTimeToFileTime(systemTime, fileTime)) { + fail("SystemTimeToFileTime failed with " + Kernel32.INSTANCE.GetLastError()); + } + + WinBase.SYSTEMTIME newSystemTime = new WinBase.SYSTEMTIME(); + if (false == Kernel32.INSTANCE.FileTimeToSystemTime(fileTime, newSystemTime)) { + fail("FileTimeToSystemTime failed with " + Kernel32.INSTANCE.GetLastError()); + } + + assertEquals(systemTime.wYear, newSystemTime.wYear); + assertEquals(systemTime.wDay, newSystemTime.wDay); + assertEquals(systemTime.wMonth, newSystemTime.wMonth); + assertEquals(systemTime.wHour, newSystemTime.wHour); + assertEquals(systemTime.wMinute, newSystemTime.wMinute); + assertEquals(systemTime.wSecond, newSystemTime.wSecond); + assertEquals(systemTime.wMilliseconds, newSystemTime.wMilliseconds); + } + + /** + * Test FILETIME's LARGE_INTEGER constructor + * @throws IOException + */ + public final void testFileTimeFromLargeInteger() throws IOException { + + File tmp = File.createTempFile("testGetFileInformationByHandleEx", "jna"); + tmp.deleteOnExit(); + + HANDLE hFile = Kernel32.INSTANCE.CreateFile(tmp.getAbsolutePath(), WinNT.GENERIC_WRITE, WinNT.FILE_SHARE_WRITE, + new WinBase.SECURITY_ATTRIBUTES(), WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); + assertFalse(WinBase.INVALID_HANDLE_VALUE.equals(hFile)); + + try { + + Memory p = new Memory(FILE_BASIC_INFO.sizeOf()); + if (false == Kernel32.INSTANCE.GetFileInformationByHandleEx(hFile, WinBase.FileBasicInfo, p, new DWORD(p.size()))) { + fail("GetFileInformationByHandleEx failed with " + Kernel32.INSTANCE.GetLastError()); + } + FILE_BASIC_INFO fbi = new FILE_BASIC_INFO(p); + FILETIME ft = new FILETIME(fbi.LastWriteTime); + SYSTEMTIME stUTC = new SYSTEMTIME(); + SYSTEMTIME stLocal = new SYSTEMTIME(); + Kernel32.INSTANCE.FileTimeToSystemTime(ft, stUTC); + // Covert to local + Kernel32.INSTANCE.SystemTimeToTzSpecificLocalTime(null, stUTC, stLocal); + FileTime calculatedCreateTime = FileTime.fromMillis(stLocal.toCalendar().getTimeInMillis()); + + // Actual file's createTime + FileTime createTime = Files.getLastModifiedTime(Paths.get(tmp.getAbsolutePath())); + + assertEquals(createTime.toMillis(), calculatedCreateTime.toMillis()); + } + finally { + Kernel32.INSTANCE.CloseHandle(hFile); + } + } + public final void testCreateRemoteThread() throws IOException { - HANDLE hThrd = Kernel32.INSTANCE.CreateRemoteThread(null, null, 0, null, null, null, null); - assertNull(hThrd); - assertEquals(Kernel32.INSTANCE.GetLastError(), WinError.ERROR_INVALID_HANDLE); + HANDLE hThrd = Kernel32.INSTANCE.CreateRemoteThread(null, null, 0, null, null, null, null); + assertNull(hThrd); + assertEquals(Kernel32.INSTANCE.GetLastError(), WinError.ERROR_INVALID_HANDLE); } public void testWriteProcessMemory() { - Kernel32 kernel = Kernel32.INSTANCE; + Kernel32 kernel = Kernel32.INSTANCE; - boolean successWrite = kernel.WriteProcessMemory(null, Pointer.NULL, Pointer.NULL, 1, null); - assertFalse(successWrite); - assertEquals(kernel.GetLastError(), WinError.ERROR_INVALID_HANDLE); - - ByteBuffer bufDest = ByteBuffer.allocateDirect(4); - bufDest.put(new byte[]{0,1,2,3}); - ByteBuffer bufSrc = ByteBuffer.allocateDirect(4); - bufSrc.put(new byte[]{5,10,15,20}); - Pointer ptrSrc = Native.getDirectBufferPointer(bufSrc); - Pointer ptrDest = Native.getDirectBufferPointer(bufDest); - - HANDLE selfHandle = kernel.GetCurrentProcess(); - kernel.WriteProcessMemory(selfHandle, ptrDest, ptrSrc, 3, null);//Write only the first three - - assertEquals(bufDest.get(0),5); - assertEquals(bufDest.get(1),10); - assertEquals(bufDest.get(2),15); - assertEquals(bufDest.get(3),3); - } + boolean successWrite = kernel.WriteProcessMemory(null, Pointer.NULL, Pointer.NULL, 1, null); + assertFalse(successWrite); + assertEquals(kernel.GetLastError(), WinError.ERROR_INVALID_HANDLE); + + ByteBuffer bufDest = ByteBuffer.allocateDirect(4); + bufDest.put(new byte[]{0,1,2,3}); + ByteBuffer bufSrc = ByteBuffer.allocateDirect(4); + bufSrc.put(new byte[]{5,10,15,20}); + Pointer ptrSrc = Native.getDirectBufferPointer(bufSrc); + Pointer ptrDest = Native.getDirectBufferPointer(bufDest); + + HANDLE selfHandle = kernel.GetCurrentProcess(); + kernel.WriteProcessMemory(selfHandle, ptrDest, ptrSrc, 3, null);//Write only the first three + + assertEquals(bufDest.get(0),5); + assertEquals(bufDest.get(1),10); + assertEquals(bufDest.get(2),15); + assertEquals(bufDest.get(3),3); + } public void testReadProcessMemory() { - Kernel32 kernel = Kernel32.INSTANCE; + Kernel32 kernel = Kernel32.INSTANCE; - boolean successRead = kernel.ReadProcessMemory(null, Pointer.NULL, Pointer.NULL, 1, null); - assertFalse(successRead); - assertEquals(kernel.GetLastError(), WinError.ERROR_INVALID_HANDLE); - - ByteBuffer bufSrc = ByteBuffer.allocateDirect(4); - bufSrc.put(new byte[]{5,10,15,20}); - ByteBuffer bufDest = ByteBuffer.allocateDirect(4); - bufDest.put(new byte[]{0,1,2,3}); - Pointer ptrSrc = Native.getDirectBufferPointer(bufSrc); - Pointer ptrDest = Native.getDirectBufferPointer(bufDest); - - HANDLE selfHandle = kernel.GetCurrentProcess(); - kernel.ReadProcessMemory(selfHandle, ptrSrc, ptrDest, 3, null);//Read only the first three - - assertEquals(bufDest.get(0),5); - assertEquals(bufDest.get(1),10); - assertEquals(bufDest.get(2),15); - assertEquals(bufDest.get(3),3); + boolean successRead = kernel.ReadProcessMemory(null, Pointer.NULL, Pointer.NULL, 1, null); + assertFalse(successRead); + assertEquals(kernel.GetLastError(), WinError.ERROR_INVALID_HANDLE); + + ByteBuffer bufSrc = ByteBuffer.allocateDirect(4); + bufSrc.put(new byte[]{5,10,15,20}); + ByteBuffer bufDest = ByteBuffer.allocateDirect(4); + bufDest.put(new byte[]{0,1,2,3}); + Pointer ptrSrc = Native.getDirectBufferPointer(bufSrc); + Pointer ptrDest = Native.getDirectBufferPointer(bufDest); + + HANDLE selfHandle = kernel.GetCurrentProcess(); + kernel.ReadProcessMemory(selfHandle, ptrSrc, ptrDest, 3, null);//Read only the first three + + assertEquals(bufDest.get(0),5); + assertEquals(bufDest.get(1),10); + assertEquals(bufDest.get(2),15); + assertEquals(bufDest.get(3),3); } public void testVirtualQueryEx() { @@ -767,167 +1277,380 @@ SIZE_T bytesRead = Kernel32.INSTANCE.VirtualQueryEx(selfHandle, Pointer.NULL, mbi, new SIZE_T(mbi.size())); assertTrue(bytesRead.intValue() > 0); } + + public void testGetCommState() { + WinBase.DCB lpDCB = new WinBase.DCB(); + // Here we test a com port that definitely does not exist! + HANDLE handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\comDummy", + WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, + null); + + int lastError = Kernel32.INSTANCE.GetLastError(); + assertEquals(lastError, WinNT.ERROR_FILE_NOT_FOUND); + //try to read the com port state using the invalid handle + assertFalse(Kernel32.INSTANCE.GetCommState(handleSerialPort, lpDCB)); + // Check if we can open a connection to com port1 + // If yes, we try to read the com state + // If no com port exists we have to skip this test + handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\com1", WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, + null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); + lastError = Kernel32.INSTANCE.GetLastError(); + if (WinNT.NO_ERROR == lastError) { + assertFalse(WinNT.INVALID_HANDLE_VALUE.equals(handleSerialPort)); + try { + lpDCB = new WinBase.DCB(); + assertTrue(Kernel32.INSTANCE.GetCommState(handleSerialPort, lpDCB)); + switch (lpDCB.BaudRate.intValue()) { + case WinBase.CBR_110: + case WinBase.CBR_1200: + case WinBase.CBR_128000: + case WinBase.CBR_14400: + case WinBase.CBR_19200: + case WinBase.CBR_2400: + case WinBase.CBR_256000: + case WinBase.CBR_300: + case WinBase.CBR_38400: + case WinBase.CBR_4800: + case WinBase.CBR_56000: + case WinBase.CBR_600: + case WinBase.CBR_9600: + break; + default: + fail("Received value of WinBase.DCB.BaudRate is not valid"); + } + } finally { + Kernel32Util.closeHandle(handleSerialPort); + } + } + } + + public void testSetCommState() { + WinBase.DCB lpDCB = new WinBase.DCB(); + // Here we test a com port that definitely does not exist! + HANDLE handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\comDummy", + WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, + null); + + int lastError = Kernel32.INSTANCE.GetLastError(); + assertEquals(lastError, WinNT.ERROR_FILE_NOT_FOUND); + // try to read the com port state using the invalid handle + assertFalse(Kernel32.INSTANCE.SetCommState(handleSerialPort, lpDCB)); + // Check if we can open a connection to com port1 + // If yes, we try to read the com state + // If no com port exists we have to skip this test + handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\com1", WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, + null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); + lastError = Kernel32.INSTANCE.GetLastError(); + if (WinNT.NO_ERROR == lastError) { + assertFalse(WinNT.INVALID_HANDLE_VALUE.equals(handleSerialPort)); + try { + lpDCB = new WinBase.DCB(); + assertTrue(Kernel32.INSTANCE.GetCommState(handleSerialPort, lpDCB)); + DWORD oldBaudRate = new DWORD(lpDCB.BaudRate.longValue()); + + lpDCB.BaudRate = new DWORD(WinBase.CBR_110); + + assertTrue(Kernel32.INSTANCE.SetCommState(handleSerialPort, lpDCB)); + WinBase.DCB lpNewDCB = new WinBase.DCB(); + assertTrue(Kernel32.INSTANCE.GetCommState(handleSerialPort, lpNewDCB)); + + assertEquals(WinBase.CBR_110, lpNewDCB.BaudRate.intValue()); + + lpDCB.BaudRate = oldBaudRate; + assertTrue(Kernel32.INSTANCE.SetCommState(handleSerialPort, lpDCB)); + + } finally { + Kernel32Util.closeHandle(handleSerialPort); + } + } + } + + public void testGetCommTimeouts() { + WinBase.COMMTIMEOUTS lpCommTimeouts = new WinBase.COMMTIMEOUTS(); + + // Here we test a com port that definitely does not exist! + HANDLE handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\comDummy", + WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, + null); + + int lastError = Kernel32.INSTANCE.GetLastError(); + assertEquals(lastError, WinNT.ERROR_FILE_NOT_FOUND); + // try to read the com port timeouts using the invalid handle + assertFalse(Kernel32.INSTANCE.GetCommTimeouts(handleSerialPort, lpCommTimeouts)); + + // Check if we can open a connection to com port1 + // If yes, we try to read the com state + // If no com port exists we have to skip this test + handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\com1", WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, + null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); + lastError = Kernel32.INSTANCE.GetLastError(); + if (WinNT.NO_ERROR == lastError) { + assertFalse(WinNT.INVALID_HANDLE_VALUE.equals(handleSerialPort)); + try { + lpCommTimeouts = new WinBase.COMMTIMEOUTS(); + assertTrue(Kernel32.INSTANCE.GetCommTimeouts(handleSerialPort, lpCommTimeouts)); + } finally { + Kernel32Util.closeHandle(handleSerialPort); + } + } + } + + public void testSetCommTimeouts() { + WinBase.COMMTIMEOUTS lpCommTimeouts = new WinBase.COMMTIMEOUTS(); + + // Here we test a com port that definitely does not exist! + HANDLE handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\comDummy", + WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, + null); + + int lastError = Kernel32.INSTANCE.GetLastError(); + assertEquals(lastError, WinNT.ERROR_FILE_NOT_FOUND); + // try to store the com port timeouts using the invalid handle + assertFalse(Kernel32.INSTANCE.SetCommTimeouts(handleSerialPort, lpCommTimeouts)); + + // Check if we can open a connection to com port1 + // If yes, we try to store the com timeouts + // If no com port exists we have to skip this test + handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\com1", WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, + null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); + lastError = Kernel32.INSTANCE.GetLastError(); + if (WinNT.NO_ERROR == lastError) { + assertFalse(WinNT.INVALID_HANDLE_VALUE.equals(handleSerialPort)); + try { + lpCommTimeouts = new WinBase.COMMTIMEOUTS(); + assertTrue(Kernel32.INSTANCE.GetCommTimeouts(handleSerialPort, lpCommTimeouts)); + + DWORD oldReadIntervalTimeout = new DWORD(lpCommTimeouts.ReadIntervalTimeout.longValue()); + + lpCommTimeouts.ReadIntervalTimeout = new DWORD(20); + + assertTrue(Kernel32.INSTANCE.SetCommTimeouts(handleSerialPort, lpCommTimeouts)); + + WinBase.COMMTIMEOUTS lpNewCommTimeouts = new WinBase.COMMTIMEOUTS(); + assertTrue(Kernel32.INSTANCE.GetCommTimeouts(handleSerialPort, lpNewCommTimeouts)); + + assertEquals(20, lpNewCommTimeouts.ReadIntervalTimeout.intValue()); + + lpCommTimeouts.ReadIntervalTimeout = oldReadIntervalTimeout; + + assertTrue(Kernel32.INSTANCE.SetCommTimeouts(handleSerialPort, lpCommTimeouts)); + + } finally { + Kernel32Util.closeHandle(handleSerialPort); + } + } + } + + public void testProcessIdToSessionId() { + int myProcessID = Kernel32.INSTANCE.GetCurrentProcessId(); + + IntByReference pSessionId = new IntByReference(); + boolean result = Kernel32.INSTANCE.ProcessIdToSessionId(myProcessID, pSessionId); + + // should give us our session ID + assertTrue("ProcessIdToSessionId should return true.", result); + + // on Win Vista and later we'll never be session 0 + // due to service isolation + // anything negative would be a definite error. + assertTrue("Session should be 1 or higher because of service isolation", pSessionId.getValue() > 0); + } + + public void testLoadLibraryEx() { + String winDir = Kernel32Util.getEnvironmentVariable("WINDIR"); + assertNotNull("No WINDIR value returned", winDir); + assertTrue("Specified WINDIR does not exist: " + winDir, new File(winDir).exists()); + + HMODULE hModule = null; + try { + hModule = Kernel32.INSTANCE.LoadLibraryEx(new File(winDir, "explorer.exe").getAbsolutePath(), null, + Kernel32.LOAD_LIBRARY_AS_DATAFILE); + if (hModule == null) { + throw new Win32Exception(Native.getLastError()); + } + assertNotNull("hModule should not be null.", hModule); + } finally { + if (hModule != null) { + if (!Kernel32.INSTANCE.FreeLibrary(hModule)) { + throw new Win32Exception(Native.getLastError()); + } + } + } + } + + public void testEnumResourceNames() { + // "14" is the type name of the My Computer icon in explorer.exe + Pointer pointer = new Memory(Native.WCHAR_SIZE * 3); + pointer.setWideString(0, "14"); + WinBase.EnumResNameProc ernp = new WinBase.EnumResNameProc() { + + @Override + public boolean invoke(HMODULE module, Pointer type, Pointer name, Pointer lParam) { + + return true; + } + }; + // null HMODULE means use this process / its EXE + // there are no type "14" resources in it. + boolean result = Kernel32.INSTANCE.EnumResourceNames(null, pointer, ernp, null); + assertFalse("EnumResourceNames should have failed.", result); + assertEquals("GetLastError should be set to 1813", WinError.ERROR_RESOURCE_TYPE_NOT_FOUND, Kernel32.INSTANCE.GetLastError()); + } + + + public void testEnumResourceTypes() { + final List types = new ArrayList(); + WinBase.EnumResTypeProc ertp = new WinBase.EnumResTypeProc() { + + @Override + public boolean invoke(HMODULE module, Pointer type, Pointer lParam) { + // simulate IS_INTRESOURCE macro defined in WinUser.h + // basically that means that if "type" is less than or equal to 65,535 + // it assumes it's an ID. + // otherwise it assumes it's a pointer to a string + if (Pointer.nativeValue(type) <= 65535) { + types.add(Pointer.nativeValue(type) + ""); + } else { + types.add(type.getWideString(0)); + } + return true; + } + }; + // null HMODULE means use this process / its EXE + // there are no type "14" resources in it. + 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); + } + + public void testModule32FirstW() { + HANDLE snapshot = Kernel32.INSTANCE.CreateToolhelp32Snapshot(Tlhelp32.TH32CS_SNAPMODULE, new DWORD(Kernel32.INSTANCE.GetCurrentProcessId())); + if (snapshot == null) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + Win32Exception we = null; + Tlhelp32.MODULEENTRY32W first = new Tlhelp32.MODULEENTRY32W(); + try { + if (!Kernel32.INSTANCE.Module32FirstW(snapshot, first)) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + + // not sure if this will be run against java.exe or javaw.exe but this + // check tests both + assertTrue("The first module in the current process should be java.exe or javaw.exe", first.szModule().startsWith("java")); + assertEquals("The process ID of the module ID should be our process ID", Kernel32.INSTANCE.GetCurrentProcessId(), first.th32ProcessID.intValue()); + } catch (Win32Exception e) { + we = e; + throw we; // re-throw so finally block is executed + } finally { + try { + Kernel32Util.closeHandle(snapshot); + } catch(Win32Exception e) { + if (we == null) { + we = e; + } else { + we.addSuppressed(e); + } + } + + if (we != null) { + throw we; + } + } + } + + public void testModule32NextW() { + HANDLE snapshot = Kernel32.INSTANCE.CreateToolhelp32Snapshot(Tlhelp32.TH32CS_SNAPMODULE, new DWORD(Kernel32.INSTANCE.GetCurrentProcessId())); + if (snapshot == null) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + Win32Exception we = null; + Tlhelp32.MODULEENTRY32W first = new Tlhelp32.MODULEENTRY32W(); + try { + if (!Kernel32.INSTANCE.Module32NextW(snapshot, first)) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + // not sure if this will be run against java.exe or javaw.exe but this + // check tests both + assertTrue("The first module in the current process should be java.exe or javaw.exe", first.szModule().startsWith("java")); + assertEquals("The process ID of the module ID should be our process ID", Kernel32.INSTANCE.GetCurrentProcessId(), first.th32ProcessID.intValue()); + } catch (Win32Exception e) { + we = e; + throw we; // re-throw so finally block is executed + } finally { + try { + Kernel32Util.closeHandle(snapshot); + } catch(Win32Exception e) { + if (we == null) { + we = e; + } else { + we.addSuppressed(e); + } + } + + if (we != null) { + throw we; + } + } + } - public void testGetCommState() { - WinBase.DCB lpDCB = new WinBase.DCB(); - // Here we test a com port that definitely does not exist! - HANDLE handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\comDummy", - WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, - null); - - int lastError = Kernel32.INSTANCE.GetLastError(); - assertEquals(lastError, WinNT.ERROR_FILE_NOT_FOUND); - //try to read the com port state using the invalid handle - assertFalse(Kernel32.INSTANCE.GetCommState(handleSerialPort, lpDCB)); - // Check if we can open a connection to com port1 - // If yes, we try to read the com state - // If no com port exists we have to skip this test - handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\com1", WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, - null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); - lastError = Kernel32.INSTANCE.GetLastError(); - if (WinNT.NO_ERROR == lastError) { - assertFalse(WinNT.INVALID_HANDLE_VALUE.equals(handleSerialPort)); - try { - lpDCB = new WinBase.DCB(); - assertTrue(Kernel32.INSTANCE.GetCommState(handleSerialPort, lpDCB)); - switch (lpDCB.BaudRate.intValue()) { - case WinBase.CBR_110: - case WinBase.CBR_1200: - case WinBase.CBR_128000: - case WinBase.CBR_14400: - case WinBase.CBR_19200: - case WinBase.CBR_2400: - case WinBase.CBR_256000: - case WinBase.CBR_300: - case WinBase.CBR_38400: - case WinBase.CBR_4800: - case WinBase.CBR_56000: - case WinBase.CBR_600: - case WinBase.CBR_9600: - break; - default: - fail("Received value of WinBase.DCB.BaudRate is not valid"); - } - } finally { - Kernel32.INSTANCE.CloseHandle(handleSerialPort); - } - } - } - - public void testSetCommState() { - WinBase.DCB lpDCB = new WinBase.DCB(); - // Here we test a com port that definitely does not exist! - HANDLE handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\comDummy", - WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, - null); - - int lastError = Kernel32.INSTANCE.GetLastError(); - assertEquals(lastError, WinNT.ERROR_FILE_NOT_FOUND); - // try to read the com port state using the invalid handle - assertFalse(Kernel32.INSTANCE.SetCommState(handleSerialPort, lpDCB)); - // Check if we can open a connection to com port1 - // If yes, we try to read the com state - // If no com port exists we have to skip this test - handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\com1", WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, - null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); - lastError = Kernel32.INSTANCE.GetLastError(); - if (WinNT.NO_ERROR == lastError) { - assertFalse(WinNT.INVALID_HANDLE_VALUE.equals(handleSerialPort)); - try { - lpDCB = new WinBase.DCB(); - assertTrue(Kernel32.INSTANCE.GetCommState(handleSerialPort, lpDCB)); - DWORD oldBaudRate = new DWORD(lpDCB.BaudRate.longValue()); - - lpDCB.BaudRate = new DWORD(WinBase.CBR_110); - - assertTrue(Kernel32.INSTANCE.SetCommState(handleSerialPort, lpDCB)); - WinBase.DCB lpNewDCB = new WinBase.DCB(); - assertTrue(Kernel32.INSTANCE.GetCommState(handleSerialPort, lpNewDCB)); - - assertEquals(WinBase.CBR_110, lpNewDCB.BaudRate.intValue()); - - lpDCB.BaudRate = oldBaudRate; - assertTrue(Kernel32.INSTANCE.SetCommState(handleSerialPort, lpDCB)); - - } finally { - Kernel32.INSTANCE.CloseHandle(handleSerialPort); - } - } - } - - public void testGetCommTimeouts() { - WinBase.COMMTIMEOUTS lpCommTimeouts = new WinBase.COMMTIMEOUTS(); - - // Here we test a com port that definitely does not exist! - HANDLE handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\comDummy", - WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, - null); - - int lastError = Kernel32.INSTANCE.GetLastError(); - assertEquals(lastError, WinNT.ERROR_FILE_NOT_FOUND); - // try to read the com port timeouts using the invalid handle - assertFalse(Kernel32.INSTANCE.GetCommTimeouts(handleSerialPort, lpCommTimeouts)); - - // Check if we can open a connection to com port1 - // If yes, we try to read the com state - // If no com port exists we have to skip this test - handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\com1", WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, - null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); - lastError = Kernel32.INSTANCE.GetLastError(); - if (WinNT.NO_ERROR == lastError) { - assertFalse(WinNT.INVALID_HANDLE_VALUE.equals(handleSerialPort)); - try { - lpCommTimeouts = new WinBase.COMMTIMEOUTS(); - assertTrue(Kernel32.INSTANCE.GetCommTimeouts(handleSerialPort, lpCommTimeouts)); - } finally { - Kernel32.INSTANCE.CloseHandle(handleSerialPort); - } - } - } - - public void testSetCommTimeouts() { - WinBase.COMMTIMEOUTS lpCommTimeouts = new WinBase.COMMTIMEOUTS(); - - // Here we test a com port that definitely does not exist! - HANDLE handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\comDummy", - WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, - null); - - int lastError = Kernel32.INSTANCE.GetLastError(); - assertEquals(lastError, WinNT.ERROR_FILE_NOT_FOUND); - // try to store the com port timeouts using the invalid handle - assertFalse(Kernel32.INSTANCE.SetCommTimeouts(handleSerialPort, lpCommTimeouts)); - - // Check if we can open a connection to com port1 - // If yes, we try to store the com timeouts - // If no com port exists we have to skip this test - handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\com1", WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, - null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); - lastError = Kernel32.INSTANCE.GetLastError(); - if (WinNT.NO_ERROR == lastError) { - assertFalse(WinNT.INVALID_HANDLE_VALUE.equals(handleSerialPort)); - try { - lpCommTimeouts = new WinBase.COMMTIMEOUTS(); - assertTrue(Kernel32.INSTANCE.GetCommTimeouts(handleSerialPort, lpCommTimeouts)); - - DWORD oldReadIntervalTimeout = new DWORD(lpCommTimeouts.ReadIntervalTimeout.longValue()); - - lpCommTimeouts.ReadIntervalTimeout = new DWORD(20); - - assertTrue(Kernel32.INSTANCE.SetCommTimeouts(handleSerialPort, lpCommTimeouts)); - - WinBase.COMMTIMEOUTS lpNewCommTimeouts = new WinBase.COMMTIMEOUTS(); - assertTrue(Kernel32.INSTANCE.GetCommTimeouts(handleSerialPort, lpNewCommTimeouts)); - - assertEquals(20, lpNewCommTimeouts.ReadIntervalTimeout.intValue()); - - lpCommTimeouts.ReadIntervalTimeout = oldReadIntervalTimeout; - - assertTrue(Kernel32.INSTANCE.SetCommTimeouts(handleSerialPort, lpCommTimeouts)); - - } finally { - Kernel32.INSTANCE.CloseHandle(handleSerialPort); - } - } - } + public void testSetErrorMode() { + // Set bit flags to 0x0001 + int previousMode = Kernel32.INSTANCE.SetErrorMode(0x0001); + // Restore to previous state; 0x0001 is now "previous" + assertEquals(Kernel32.INSTANCE.SetErrorMode(previousMode), 0x0001); + } + +// Testcase is disabled, as kernel32 ordinal values are not stable. +// a library with a stable function <-> ordinal value is needed. +// +// /** +// * Test that a named function on win32 can be equally resolved by its ordinal +// * value. +// * +// * From link.exe /dump /exports c:\\Windows\\System32\\kernel32.dll +// * +// * 746 2E9 0004FA20 GetTapeStatus +// * 747 2EA 0002DB20 GetTempFileNameA +// * 748 2EB 0002DB30 GetTempFileNameW +// * 749 2EC 0002DB40 GetTempPathA +// * 750 2ED 0002DB50 GetTempPathW +// * 751 2EE 00026780 GetThreadContext +// * +// * The tested function is GetTempPathW which is mapped to the ordinal 750. +// */ +// public void testGetProcAddress() { +// NativeLibrary kernel32Library = NativeLibrary.getInstance("kernel32"); +// // get module handle needed to resolve function pointer via GetProcAddress +// HMODULE kernel32Module = Kernel32.INSTANCE.GetModuleHandle("kernel32"); +// +// Function namedFunction = kernel32Library.getFunction("GetTempPathW"); +// long namedFunctionPointerValue = Pointer.nativeValue(namedFunction); +// +// Pointer ordinalFunction = Kernel32.INSTANCE.GetProcAddress(kernel32Module, 750); +// long ordinalFunctionPointerValue = Pointer.nativeValue(ordinalFunction); +// +// assertEquals(namedFunctionPointerValue, ordinalFunctionPointerValue); +// } + + public void testSetThreadExecutionState() { + int originalExecutionState = Kernel32.INSTANCE.SetThreadExecutionState( + WinBase.ES_CONTINUOUS | WinBase.ES_SYSTEM_REQUIRED | WinBase.ES_AWAYMODE_REQUIRED + ); + + assert originalExecutionState > 0; + + int intermediateExecutionState = Kernel32.INSTANCE.SetThreadExecutionState( + WinBase.ES_CONTINUOUS + ); + + assertEquals(WinBase.ES_CONTINUOUS | WinBase.ES_SYSTEM_REQUIRED | WinBase.ES_AWAYMODE_REQUIRED, intermediateExecutionState); + + Kernel32.INSTANCE.SetThreadExecutionState(originalExecutionState); + } } diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/Kernel32UtilTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/Kernel32UtilTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/Kernel32UtilTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/Kernel32UtilTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,14 @@ /* Copyright (c) 2010, 2013 Daniel Doubrovkine, Markus Karg, All Rights Reserved - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * Lesser General Public License for more details. */ package com.sun.jna.platform.win32; @@ -20,7 +20,13 @@ import java.io.IOException; import java.io.PrintWriter; import java.util.Collection; +import java.util.List; +import java.util.Map; +import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.Tlhelp32.MODULEENTRY32W; +import com.sun.jna.platform.win32.WinNT.HANDLE; +import com.sun.jna.platform.win32.WinNT.HRESULT; import com.sun.jna.platform.win32.WinNT.LARGE_INTEGER; import junit.framework.TestCase; @@ -30,111 +36,143 @@ * @author markus[at]headcrashing[dot]eu */ public class Kernel32UtilTest extends TestCase { - + public static void main(String[] args) throws Exception { System.out.println("Computer name: " + Kernel32Util.getComputerName()); System.out.println("Temp path: " + Kernel32Util.getTempPath()); // logical drives System.out.println("Logical drives: "); - Collection logicalDrives = Kernel32Util.getLogicalDriveStrings(); - for(String logicalDrive : logicalDrives) { - // drive type - System.out.println(" " + logicalDrive + " (" - + Kernel32.INSTANCE.GetDriveType(logicalDrive) + ")"); - // free space - LARGE_INTEGER.ByReference lpFreeBytesAvailable = new LARGE_INTEGER.ByReference(); - LARGE_INTEGER.ByReference lpTotalNumberOfBytes = new LARGE_INTEGER.ByReference(); - LARGE_INTEGER.ByReference lpTotalNumberOfFreeBytes = new LARGE_INTEGER.ByReference(); - if (Kernel32.INSTANCE.GetDiskFreeSpaceEx(logicalDrive, lpFreeBytesAvailable, lpTotalNumberOfBytes, lpTotalNumberOfFreeBytes)) { - System.out.println(" Total: " + formatBytes(lpTotalNumberOfBytes.getValue())); - System.out.println(" Free: " + formatBytes(lpTotalNumberOfFreeBytes.getValue())); - } - } - - junit.textui.TestRunner.run(Kernel32UtilTest.class); - } - - /** - * Format bytes. - * @param bytes - * Bytes. - * @return - * Rounded string representation of the byte size. - */ + Collection logicalDrives = Kernel32Util.getLogicalDriveStrings(); + for(String logicalDrive : logicalDrives) { + // drive type + System.out.println(" " + logicalDrive + " (" + + Kernel32.INSTANCE.GetDriveType(logicalDrive) + ")"); + // free space + LARGE_INTEGER.ByReference lpFreeBytesAvailable = new LARGE_INTEGER.ByReference(); + LARGE_INTEGER.ByReference lpTotalNumberOfBytes = new LARGE_INTEGER.ByReference(); + LARGE_INTEGER.ByReference lpTotalNumberOfFreeBytes = new LARGE_INTEGER.ByReference(); + if (Kernel32.INSTANCE.GetDiskFreeSpaceEx(logicalDrive, lpFreeBytesAvailable, lpTotalNumberOfBytes, lpTotalNumberOfFreeBytes)) { + System.out.println(" Total: " + formatBytes(lpTotalNumberOfBytes.getValue())); + System.out.println(" Free: " + formatBytes(lpTotalNumberOfFreeBytes.getValue())); + } + } + + junit.textui.TestRunner.run(Kernel32UtilTest.class); + } + + /** + * Format bytes. + * @param bytes + * Bytes. + * @return + * Rounded string representation of the byte size. + */ private static String formatBytes(long bytes) { - if (bytes == 1) { // bytes - return String.format("%d byte", bytes); - } else if (bytes < 1024) { // bytes - return String.format("%d bytes", bytes); - } else if (bytes < 1048576 && bytes % 1024 == 0) { // Kb - return String.format("%.0f KB", (double) bytes / 1024); - } else if (bytes < 1048576) { // Kb - return String.format("%.1f KB", (double) bytes / 1024); - } else if (bytes % 1048576 == 0 && bytes < 1073741824) { // Mb - return String.format("%.0f MB", (double) bytes / 1048576); - } else if (bytes < 1073741824) { // Mb - return String.format("%.1f MB", (double) bytes / 1048576); - } else if (bytes % 1073741824 == 0 && bytes < 1099511627776L) { // GB - return String.format("%.0f GB", (double) bytes / 1073741824); - } else if (bytes < 1099511627776L ) { - return String.format("%.1f GB", (double) bytes / 1073741824); - } else if (bytes % 1099511627776L == 0 && bytes < 1125899906842624L) { // TB - return String.format("%.0f TB", (double) bytes / 1099511627776L); - } else if (bytes < 1125899906842624L ) { - return String.format("%.1f TB", (double) bytes / 1099511627776L); - } else { - return String.format("%d bytes", bytes); - } - } - - public void testGetComputerName() { - assertTrue(Kernel32Util.getComputerName().length() > 0); - } - - public void testFormatMessageFromLastErrorCode() { - assertEquals("The remote server has been paused or is in the process of being started.", - Kernel32Util.formatMessageFromLastErrorCode(W32Errors.ERROR_SHARING_PAUSED)); - } - - public void testFormatMessageFromHR() { - assertEquals("The operation completed successfully.", - Kernel32Util.formatMessage(W32Errors.S_OK)); - } - - public void testGetTempPath() { - assertTrue(Kernel32Util.getTempPath().length() > 0); - } - - public void testGetLogicalDriveStrings() { - Collection logicalDrives = Kernel32Util.getLogicalDriveStrings(); - assertTrue("No logical drives found", logicalDrives.size() > 0); - for(String logicalDrive : logicalDrives) { - assertTrue("Empty logical drive name in list", logicalDrive.length() > 0); - } - } - - public void testDeleteFile() throws IOException { - String filename = Kernel32Util.getTempPath() + "\\FileDoesNotExist.jna"; - File f = new File(filename); - f.createNewFile(); - Kernel32Util.deleteFile(filename); - } - - public void testGetFileAttributes() throws IOException { - String filename = Kernel32Util.getTempPath(); - int fileAttributes = Kernel32Util.getFileAttributes(filename); - assertEquals(WinNT.FILE_ATTRIBUTE_DIRECTORY, fileAttributes & WinNT.FILE_ATTRIBUTE_DIRECTORY); - File tempFile = File.createTempFile("jna", "tmp"); - tempFile.deleteOnExit(); - int fileAttributes2 = Kernel32Util.getFileAttributes(tempFile.getAbsolutePath()); - tempFile.delete(); - assertEquals(0, fileAttributes2 & WinNT.FILE_ATTRIBUTE_DIRECTORY); - } - + if (bytes == 1) { // bytes + return String.format("%d byte", bytes); + } else if (bytes < 1024) { // bytes + return String.format("%d bytes", bytes); + } else if (bytes < 1048576 && bytes % 1024 == 0) { // Kb + return String.format("%.0f KB", (double) bytes / 1024); + } else if (bytes < 1048576) { // Kb + return String.format("%.1f KB", (double) bytes / 1024); + } else if (bytes % 1048576 == 0 && bytes < 1073741824) { // Mb + return String.format("%.0f MB", (double) bytes / 1048576); + } else if (bytes < 1073741824) { // Mb + return String.format("%.1f MB", (double) bytes / 1048576); + } else if (bytes % 1073741824 == 0 && bytes < 1099511627776L) { // GB + return String.format("%.0f GB", (double) bytes / 1073741824); + } else if (bytes < 1099511627776L ) { + return String.format("%.1f GB", (double) bytes / 1073741824); + } else if (bytes % 1099511627776L == 0 && bytes < 1125899906842624L) { // TB + return String.format("%.0f TB", (double) bytes / 1099511627776L); + } else if (bytes < 1125899906842624L ) { + return String.format("%.1f TB", (double) bytes / 1099511627776L); + } else { + return String.format("%d bytes", bytes); + } + } + + public void testFreeLocalMemory() { + try { + Pointer ptr = new Pointer(0xFFFFFFFFFFFFFFFFL); + Kernel32Util.freeLocalMemory(ptr); + fail("Unexpected success to free bad local memory"); + } catch(Win32Exception e) { + HRESULT hr = e.getHR(); + int code = W32Errors.HRESULT_CODE(hr.intValue()); + assertEquals("Mismatched failure reason code", WinError.ERROR_INVALID_HANDLE, code); + } + } + + public void testFreeGlobalMemory() { + try { + Pointer ptr = new Pointer(0xFFFFFFFFFFFFFFFFL); + Kernel32Util.freeGlobalMemory(ptr); + fail("Unexpected success to free bad global memory"); + } catch(Win32Exception e) { + HRESULT hr = e.getHR(); + int code = W32Errors.HRESULT_CODE(hr.intValue()); + assertEquals("Mismatched failure reason code", WinError.ERROR_INVALID_HANDLE, code); + } + } + + public void testGetComputerName() { + assertTrue(Kernel32Util.getComputerName().length() > 0); + } + + public void testFormatMessageFromLastErrorCode() { + if (AbstractWin32TestSupport.isEnglishLocale) { + assertEquals("The remote server has been paused or is in the process of being started.", + Kernel32Util.formatMessageFromLastErrorCode(W32Errors.ERROR_SHARING_PAUSED)); + } else { + System.out.println("testFormatMessageFromLastErrorCode Test can only be run on english locale"); + } + } + + public void testFormatMessageFromHR() { + if(AbstractWin32TestSupport.isEnglishLocale) { + assertEquals("The operation completed successfully.", + Kernel32Util.formatMessage(W32Errors.S_OK)); + } else { + System.out.println("testFormatMessageFromHR Test can only be run on english locale"); + } + } + + public void testGetTempPath() { + assertTrue(Kernel32Util.getTempPath().length() > 0); + } + + public void testGetLogicalDriveStrings() { + Collection logicalDrives = Kernel32Util.getLogicalDriveStrings(); + assertTrue("No logical drives found", logicalDrives.size() > 0); + for(String logicalDrive : logicalDrives) { + assertTrue("Empty logical drive name in list", logicalDrive.length() > 0); + } + } + + public void testDeleteFile() throws IOException { + String filename = Kernel32Util.getTempPath() + "\\FileDoesNotExist.jna"; + File f = new File(filename); + f.createNewFile(); + Kernel32Util.deleteFile(filename); + } + + public void testGetFileAttributes() throws IOException { + String filename = Kernel32Util.getTempPath(); + int fileAttributes = Kernel32Util.getFileAttributes(filename); + assertEquals(WinNT.FILE_ATTRIBUTE_DIRECTORY, fileAttributes & WinNT.FILE_ATTRIBUTE_DIRECTORY); + File tempFile = File.createTempFile("jna", "tmp"); + tempFile.deleteOnExit(); + int fileAttributes2 = Kernel32Util.getFileAttributes(tempFile.getAbsolutePath()); + tempFile.delete(); + assertEquals(0, fileAttributes2 & WinNT.FILE_ATTRIBUTE_DIRECTORY); + } + public void testGetEnvironmentVariable() { - assertEquals(null, Kernel32Util.getEnvironmentVariable("jna-getenvironment-test")); - Kernel32.INSTANCE.SetEnvironmentVariable("jna-getenvironment-test", "42"); - assertEquals("42", Kernel32Util.getEnvironmentVariable("jna-getenvironment-test")); + assertEquals(null, Kernel32Util.getEnvironmentVariable("jna-getenvironment-test")); + Kernel32.INSTANCE.SetEnvironmentVariable("jna-getenvironment-test", "42"); + assertEquals("42", Kernel32Util.getEnvironmentVariable("jna-getenvironment-test")); } public final void testGetPrivateProfileInt() throws IOException { @@ -173,7 +211,7 @@ 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")); @@ -181,7 +219,7 @@ assertEquals(reader.readLine(), null); reader.close(); } - + public final void testGetPrivateProfileSection() throws IOException { final File tmp = File.createTempFile("testGetPrivateProfileSection", ".ini"); tmp.deleteOnExit(); @@ -251,6 +289,57 @@ assertEquals(reader.readLine(), "foo=bar"); } finally { reader.close(); - } + } + } + + public final void testQueryFullProcessImageName() { + HANDLE h = Kernel32.INSTANCE.OpenProcess(WinNT.PROCESS_QUERY_INFORMATION, false, Kernel32.INSTANCE.GetCurrentProcessId()); + assertNotNull("Failed (" + Kernel32.INSTANCE.GetLastError() + ") to get process handle", h); + try { + String name = Kernel32Util.QueryFullProcessImageName(h, 0); + assertTrue("Failed to query process image name, empty path returned", name.length() > 0); + } finally { + Kernel32Util.closeHandle(h); + } + } + + public void testGetResource() { + String winDir = Kernel32Util.getEnvironmentVariable("WINDIR"); + assertNotNull("No WINDIR value returned", winDir); + assertTrue("Specified WINDIR does not exist: " + winDir, new File(winDir).exists()); + + // On Windows 7, "14" is the type assigned to the "My Computer" icon + // (which is named "ICO_MYCOMPUTER") + byte[] results = Kernel32Util.getResource(new File(winDir, "explorer.exe").getAbsolutePath(), "14", + "ICO_MYCOMPUTER"); + assertNotNull("The 'ICO_MYCOMPUTER' resource in explorer.exe should have some content.", results); + assertTrue("The 'ICO_MYCOMPUTER' resource in explorer.exe should have some content.", results.length > 0); + } + + public void testGetResourceNames() { + String winDir = Kernel32Util.getEnvironmentVariable("WINDIR"); + assertNotNull("No WINDIR value returned", winDir); + assertTrue("Specified WINDIR does not exist: " + winDir, new File(winDir).exists()); + + // On Windows 7, "14" is the type assigned to the "My Computer" icon + // (which is named "ICO_MYCOMPUTER") + Map> names = Kernel32Util.getResourceNames(new File(winDir, "explorer.exe").getAbsolutePath()); + + assertNotNull("explorer.exe should contain some resources in it.", names); + assertTrue("explorer.exe should contain some resource types in it.", names.size() > 0); + assertTrue("explorer.exe should contain a resource of type '14' in it.", names.containsKey("14")); + assertTrue("resource type 14 should have a name named ICO_MYCOMPUTER associated with it.", names.get("14").contains("ICO_MYCOMPUTER")); + } + + public void testGetModules() { + List results = Kernel32Util.getModules(Kernel32.INSTANCE.GetCurrentProcessId()); + + // not sure if this will be run against java.exe or javaw.exe but these checks should work with both + assertNotNull("There should be some modules returned from this helper", results); + assertTrue("The first module in this process should be java.exe or javaw.exe", results.get(0).szModule().startsWith("java")); + + // since this is supposed to return all the modules in a process, there should be an EXE and at least 1 Windows DLL + // so assert total count is at least two + assertTrue("This is supposed to return all the modules in a process, so there should be an EXE and at least 1 Windows API DLL.", results.size() > 2); } } diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/Kernel32VolumeManagementFunctionsTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/Kernel32VolumeManagementFunctionsTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/Kernel32VolumeManagementFunctionsTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/Kernel32VolumeManagementFunctionsTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -136,12 +136,15 @@ char[] lpszVolumeName = new char[WinDef.MAX_PATH + 1]; HANDLE hFindVolume = assertValidHandle("FindFirstVolume", Kernel32.INSTANCE.FindFirstVolume(lpszVolumeName, lpszVolumeName.length)); try { + int foundPaths = 0; do { String volumeGUID = Native.toString(lpszVolumeName); testEnumVolumeMountMoints(volumeGUID); - testGetVolumePathNamesForVolumeName(volumeGUID); + foundPaths += testGetVolumePathNamesForVolumeName(volumeGUID); } while(Kernel32.INSTANCE.FindNextVolume(hFindVolume, lpszVolumeName, lpszVolumeName.length)); + assertTrue("No paths were found", foundPaths > 0); + int hr = Kernel32.INSTANCE.GetLastError(); assertEquals("Bad volumes enum termination reason", WinError.ERROR_NO_MORE_FILES, hr); } finally { @@ -149,13 +152,13 @@ } } - private void testGetVolumePathNamesForVolumeName(String lpszVolumeName) { + private int testGetVolumePathNamesForVolumeName(String lpszVolumeName) { Collection paths = Kernel32Util.getVolumePathNamesForVolumeName(lpszVolumeName); - assertTrue("No paths for volume " + lpszVolumeName, paths.size() > 0); for (String p : paths) { // System.out.append('\t').append("testGetVolumePathNamesForVolumeName").append('[').append(lpszVolumeName).append(']').append(" - ").println(p); assertTrue("Empty path for volume " + lpszVolumeName, p.length() > 0); } + return paths.size(); } private void testEnumVolumeMountMoints(String volumeGUID) { @@ -164,7 +167,9 @@ if (WinNT.INVALID_HANDLE_VALUE.equals(hFindVolumeMountPoint)) { int hr = Kernel32.INSTANCE.GetLastError(); if ((hr == WinError.ERROR_ACCESS_DENIED) // e.g., network or hidden volumes - || (hr == WinError.ERROR_NOT_READY)) { // e.g., DVD drive + || (hr == WinError.ERROR_NOT_READY) // e.g., DVD drive + || (hr == WinError.ERROR_NO_MORE_FILES) // No folders found + || (hr == WinError.ERROR_PATH_NOT_FOUND)) { // System.out.append('\t').append('[').append(volumeGUID).append(']').append(" - skipped: reason=").println(hr); return; } diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/MprTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/MprTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/MprTest.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/MprTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,330 @@ +/* Copyright (c) 2015 Adam Marcionek, All Rights Reserved + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ + +package com.sun.jna.platform.win32; + +import java.io.File; + +import com.sun.jna.Memory; +import com.sun.jna.platform.win32.LMShare.SHARE_INFO_2; +import com.sun.jna.platform.win32.WinNT.HANDLEByReference; +import com.sun.jna.platform.win32.Winnetwk.ConnectFlag; +import com.sun.jna.platform.win32.Winnetwk.NETRESOURCE; +import com.sun.jna.platform.win32.Winnetwk.REMOTE_NAME_INFO; +import com.sun.jna.platform.win32.Winnetwk.RESOURCESCOPE; +import com.sun.jna.platform.win32.Winnetwk.RESOURCETYPE; +import com.sun.jna.platform.win32.Winnetwk.RESOURCEUSAGE; +import com.sun.jna.platform.win32.Winnetwk.UNIVERSAL_NAME_INFO; +import com.sun.jna.ptr.IntByReference; + +import junit.framework.TestCase; + +/** + * @author amarcionek[at]gmail[dot]com + */ +public class MprTest extends TestCase { + + public static void main(String[] args) throws Exception { + junit.textui.TestRunner.run(MprTest.class); + } + + public void testCreateLocalShare() throws Exception { + File fileShareFolder = createTempFolder(); + String share = createLocalShare(fileShareFolder); + Netapi32.INSTANCE.NetShareDel(null, share, 0); + } + + public void testWNetUseConnection() throws Exception { + // First create a share on the local machine + File fileShareFolder = createTempFolder(); + String share = createLocalShare(fileShareFolder); + + NETRESOURCE resource = new NETRESOURCE(); + + resource.dwDisplayType = 0; + resource.dwScope = 0; + resource.dwType = RESOURCETYPE.RESOURCETYPE_DISK; + resource.lpRemoteName = "\\\\" + getLocalComputerName() + "\\" + share; + + try { + // Cancel any existing connections of the same name + Mpr.INSTANCE.WNetCancelConnection2(resource.lpRemoteName, 0, true); + // Establish a new one + assertEquals(WinError.ERROR_SUCCESS, Mpr.INSTANCE.WNetUseConnection(null, resource, null, null, 0, null, null, null)); + } finally { + // Clean up resources + Mpr.INSTANCE.WNetCancelConnection2(resource.lpRemoteName, 0, true); + Netapi32.INSTANCE.NetShareDel(null, share, 0); + fileShareFolder.delete(); + } + } + + public void testWNetAddConnection3() throws Exception { + // First create a share on the local machine + File fileShareFolder = createTempFolder(); + String share = createLocalShare(fileShareFolder); + + NETRESOURCE resource = new NETRESOURCE(); + + resource.dwDisplayType = 0; + resource.dwScope = 0; + resource.dwType = RESOURCETYPE.RESOURCETYPE_DISK; + resource.lpRemoteName = "\\\\" + getLocalComputerName() + "\\" + share; + + try { + // Cancel any existing connections of the same name + Mpr.INSTANCE.WNetCancelConnection2(resource.lpRemoteName, 0, true); + // Establish a new one + assertEquals(WinError.ERROR_SUCCESS, Mpr.INSTANCE.WNetAddConnection3(null, resource, null, null, 0)); + } finally { + // Clean up resources + Mpr.INSTANCE.WNetCancelConnection2(resource.lpRemoteName, 0, true); + Netapi32.INSTANCE.NetShareDel(null, share, 0); + fileShareFolder.delete(); + } + } + + public void testWNetOpenCloseConnection() throws Exception { + HANDLEByReference lphEnum = new HANDLEByReference(); + assertEquals(WinError.ERROR_SUCCESS, Mpr.INSTANCE.WNetOpenEnum(RESOURCESCOPE.RESOURCE_CONNECTED, RESOURCETYPE.RESOURCETYPE_DISK, + RESOURCEUSAGE.RESOURCEUSAGE_ALL, null, lphEnum)); + assertEquals(WinError.ERROR_SUCCESS, Mpr.INSTANCE.WNetCloseEnum(lphEnum.getValue())); + } + + public void testWNetEnumConnection() throws Exception { + int bufferSize = 16 * 1024; // MSDN recommends this as a reasonable size + HANDLEByReference lphEnum = new HANDLEByReference(); + + // Create a local share and connect to it. This ensures the enum will + // find at least one entry. + File fileShareFolder = createTempFolder(); + String share = createLocalShare(fileShareFolder); + // Connect to local share + connectToLocalShare(share, null); + + try { + + // Open an enumeration + assertEquals(WinError.ERROR_SUCCESS, Mpr.INSTANCE.WNetOpenEnum(RESOURCESCOPE.RESOURCE_CONNECTED, RESOURCETYPE.RESOURCETYPE_DISK, + RESOURCEUSAGE.RESOURCEUSAGE_ALL, null, lphEnum)); + + int winError = WinError.ERROR_SUCCESS; + + while (true) { + + Memory memory = new Memory(bufferSize); + + IntByReference lpBufferSize = new IntByReference(bufferSize); + IntByReference lpcCount = new IntByReference(1); + + // Get next value + winError = Mpr.INSTANCE.WNetEnumResource(lphEnum.getValue(), lpcCount, memory, lpBufferSize); + + // Reached end of enumeration + if (winError == WinError.ERROR_NO_MORE_ITEMS) + break; + + // Unlikely, but means our buffer size isn't large enough. + if (winError == WinError.ERROR_MORE_DATA) { + bufferSize = bufferSize * 2; + continue; + } + + // If we get here, it means it has to be a success or our + // programming logic was wrong. + assertEquals(winError, WinError.ERROR_SUCCESS); + + // Asked for one, should only get one. + assertEquals(1, lpcCount.getValue()); + + // Create a NETRESOURCE based on the memory + NETRESOURCE resource = new NETRESOURCE(memory); + + // Assert things we know for sure. + assertNotNull(resource.lpRemoteName); + } + + // Expect ERROR_NO_MORE_ITEMS here. + assertEquals(winError, WinError.ERROR_NO_MORE_ITEMS); + } finally { + // Clean up resources + Mpr.INSTANCE.WNetCloseEnum(lphEnum.getValue()); + disconnectFromLocalShare("\\\\" + getLocalComputerName() + "\\" + share); + deleteLocalShare(share); + fileShareFolder.delete(); + } + } + + public void testWNetGetUniversalName() throws Exception { + int bufferSize = 1024; // MSDN recommends this as a reasonable size + Memory memory = new Memory(bufferSize); + IntByReference lpBufferSize = new IntByReference(bufferSize); + File file = null; + String share = null; + String driveLetter = new String("x:"); + File fileShareFolder = createTempFolder(); + + try { + // Create a local share and connect to it. + share = createLocalShare(fileShareFolder); + // Connect to share using a drive letter. + connectToLocalShare(share, driveLetter); + + // Create a path on local device redirected to the share. + String filePath = new String(driveLetter + "\\testfile.txt"); + file = new File(filePath); + file.createNewFile(); + + // Test WNetGetUniversalName using UNIVERSAL_NAME_INFO_LEVEL + assertEquals(WinError.ERROR_SUCCESS, + Mpr.INSTANCE.WNetGetUniversalName(filePath, Winnetwk.UNIVERSAL_NAME_INFO_LEVEL, memory, lpBufferSize)); + + UNIVERSAL_NAME_INFO uinfo = new UNIVERSAL_NAME_INFO(memory); + assertNotNull(uinfo.lpUniversalName); + + // Test WNetGetUniversalName using REMOTE_NAME_INFO_LEVEL + assertEquals(WinError.ERROR_SUCCESS, + Mpr.INSTANCE.WNetGetUniversalName(filePath, Winnetwk.REMOTE_NAME_INFO_LEVEL, memory, lpBufferSize)); + + REMOTE_NAME_INFO rinfo = new REMOTE_NAME_INFO(memory); + assertNotNull(rinfo.lpUniversalName); + assertNotNull(rinfo.lpConnectionName); + assertNotNull(rinfo.lpRemainingPath); + } finally { + // Clean up resources + if (file != null) + file.delete(); + if (share != null) { + disconnectFromLocalShare(driveLetter); + deleteLocalShare(share); + fileShareFolder.delete(); + } + } + } + + private static File createTempFolder() throws Exception { + String folderPath = System.getProperty("java.io.tmpdir") + File.separatorChar + System.nanoTime(); + File file = new File(folderPath); + file.mkdir(); + return file; + } + + /** + * Get local NETBIOS machine name + * + * @return String with machine name + * @throws Exception + */ + private String getLocalComputerName() throws Exception { + IntByReference lpnSize = new IntByReference(0); + // Get size of char array + Kernel32.INSTANCE.GetComputerName(null, lpnSize); + assertEquals(WinError.ERROR_BUFFER_OVERFLOW, Kernel32.INSTANCE.GetLastError()); + // Allocate character array + char buffer[] = new char[WinBase.MAX_COMPUTERNAME_LENGTH + 1]; + lpnSize.setValue(buffer.length); + assertTrue(Kernel32.INSTANCE.GetComputerName(buffer, lpnSize)); + // Return string with computer name + String computerName = new String(buffer); + computerName = computerName.trim(); + return computerName; + } + + /** + * Create a share on the local machine. Uses a temporary directory and + * shares it out with ACCESS_ALL + * + * @param shareFolder + * the full path local folder to share + * @return String with the share name, essentially the top level folder + * name. + * @throws Exception + * the exception + */ + private String createLocalShare(File shareFolder) throws Exception { + + SHARE_INFO_2 shi = new SHARE_INFO_2(); + shi.shi2_netname = shareFolder.getName(); + shi.shi2_type = LMShare.STYPE_DISKTREE; + shi.shi2_remark = ""; + shi.shi2_permissions = LMAccess.ACCESS_ALL; + shi.shi2_max_uses = -1; + shi.shi2_current_uses = 0; + shi.shi2_path = shareFolder.getAbsolutePath(); + shi.shi2_passwd = ""; + + // Write from struct to native memory. + shi.write(); + + IntByReference parm_err = new IntByReference(0); + int errorCode = Netapi32.INSTANCE.NetShareAdd(null, // Use local computer + 2, shi.getPointer(), parm_err); + assertEquals( + String.format("Failed to create share - errorCode: %d (Param: %d)", errorCode, parm_err.getValue()), + LMErr.NERR_Success, errorCode); + + return shareFolder.getName(); + } + + /** + * Delete a local share + * + * @param share + */ + private void deleteLocalShare(String share) { + Netapi32.INSTANCE.NetShareDel(null, share, 0); + } + + /** + * Connect to a local share on the local machine. Assumes the share is + * already present + * + * @param share + * name of share on local computer. + * @param lpLocalName + * name of local device to redirect to. E.g. F:. If null, makes a + * connection without redirecting. + * @throws Exception + * the exception + */ + private void connectToLocalShare(String share, String lpLocalName) throws Exception { + NETRESOURCE resource = new NETRESOURCE(); + + resource.dwDisplayType = 0; + resource.dwScope = 0; + resource.dwType = RESOURCETYPE.RESOURCETYPE_DISK; + resource.lpLocalName = lpLocalName; + resource.lpRemoteName = "\\\\" + getLocalComputerName() + "\\" + share; + + // Establish connection + assertEquals(WinError.ERROR_SUCCESS, Mpr.INSTANCE.WNetAddConnection3(null, resource, null, null, 0)); + } + + /** + * Disconnect from a share. + * + * @param lpName + * [in] Pointer to a constant null-terminated string that + * specifies the name of either the redirected local device or + * the remote network resource to disconnect from. If this + * parameter specifies a redirected local device, the function + * cancels only the specified device redirection. If the + * parameter specifies a remote network resource, all connections + * without devices are canceled. + */ + private void disconnectFromLocalShare(String lpName) { + // Remove connection + Mpr.INSTANCE.WNetCancelConnection2(lpName, ConnectFlag.CONNECT_UPDATE_PROFILE, true); + } +} diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/Netapi32Test.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/Netapi32Test.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/Netapi32Test.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/Netapi32Test.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,26 +1,27 @@ /* Copyright (c) 2010 Daniel Doubrovkine, All Rights Reserved - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * Lesser General Public License for more details. */ package com.sun.jna.platform.win32; -import junit.framework.TestCase; +import java.io.File; -import com.sun.jna.WString; import com.sun.jna.platform.win32.DsGetDC.DS_DOMAIN_TRUSTS; import com.sun.jna.platform.win32.DsGetDC.PDOMAIN_CONTROLLER_INFO; import com.sun.jna.platform.win32.LMAccess.GROUP_INFO_2; import com.sun.jna.platform.win32.LMAccess.GROUP_USERS_INFO_0; import com.sun.jna.platform.win32.LMAccess.LOCALGROUP_USERS_INFO_0; import com.sun.jna.platform.win32.LMAccess.USER_INFO_1; +import com.sun.jna.platform.win32.LMShare.SHARE_INFO_2; +import com.sun.jna.platform.win32.LMShare.SHARE_INFO_502; import com.sun.jna.platform.win32.NTSecApi.LSA_FOREST_TRUST_RECORD; import com.sun.jna.platform.win32.NTSecApi.PLSA_FOREST_TRUST_INFORMATION; import com.sun.jna.platform.win32.NTSecApi.PLSA_FOREST_TRUST_RECORD; @@ -29,6 +30,8 @@ import com.sun.jna.ptr.IntByReference; import com.sun.jna.ptr.PointerByReference; +import junit.framework.TestCase; + /** * @author dblock[at]dblock[dot]org */ @@ -50,16 +53,16 @@ assertEquals(W32Errors.ERROR_SUCCESS, Netapi32.INSTANCE.NetApiBufferFree( lpNameBuffer.getValue())); } - + public void testNetGetLocalGroups() { for(int i = 0; i < 2; i++) { PointerByReference bufptr = new PointerByReference(); IntByReference entriesRead = new IntByReference(); - IntByReference totalEntries = new IntByReference(); - assertEquals(LMErr.NERR_Success, Netapi32.INSTANCE.NetLocalGroupEnum(null, i, bufptr, - LMCons.MAX_PREFERRED_LENGTH, - entriesRead, - totalEntries, + IntByReference totalEntries = new IntByReference(); + assertEquals(LMErr.NERR_Success, Netapi32.INSTANCE.NetLocalGroupEnum(null, i, bufptr, + LMCons.MAX_PREFERRED_LENGTH, + entriesRead, + totalEntries, null)); assertTrue(entriesRead.getValue() > 0); assertEquals(totalEntries.getValue(), entriesRead.getValue()); @@ -67,11 +70,11 @@ bufptr.getValue())); } } - + public void testNetGetDCName() { PointerByReference lpNameBuffer = new PointerByReference(); IntByReference BufferType = new IntByReference(); - assertEquals(LMErr.NERR_Success, Netapi32.INSTANCE.NetGetJoinInformation(null, lpNameBuffer, BufferType)); + assertEquals(LMErr.NERR_Success, Netapi32.INSTANCE.NetGetJoinInformation(null, lpNameBuffer, BufferType)); if (BufferType.getValue() == LMJoin.NETSETUP_JOIN_STATUS.NetSetupDomainName) { PointerByReference bufptr = new PointerByReference(); assertEquals(LMErr.NERR_Success, Netapi32.INSTANCE.NetGetDCName(null, null, bufptr)); @@ -81,7 +84,7 @@ } assertEquals(W32Errors.ERROR_SUCCESS, Netapi32.INSTANCE.NetApiBufferFree(lpNameBuffer.getValue())); } - + public void testNetUserGetGroups() { User[] users = Netapi32Util.getUsers(); assertTrue(users.length >= 1); @@ -89,16 +92,16 @@ IntByReference entriesread = new IntByReference(); IntByReference totalentries = new IntByReference(); assertEquals(LMErr.NERR_Success, Netapi32.INSTANCE.NetUserGetGroups( - null, users[0].name, 0, bufptr, LMCons.MAX_PREFERRED_LENGTH, + null, users[0].name, 0, bufptr, LMCons.MAX_PREFERRED_LENGTH, entriesread, totalentries)); - GROUP_USERS_INFO_0 lgroup = new GROUP_USERS_INFO_0(bufptr.getValue()); + GROUP_USERS_INFO_0 lgroup = new GROUP_USERS_INFO_0(bufptr.getValue()); GROUP_USERS_INFO_0[] lgroups = (GROUP_USERS_INFO_0[]) lgroup.toArray(entriesread.getValue()); for (GROUP_USERS_INFO_0 localGroupInfo : lgroups) { assertTrue(localGroupInfo.grui0_name.length() > 0); } assertEquals(LMErr.NERR_Success, Netapi32.INSTANCE.NetApiBufferFree(bufptr.getValue())); } - + public void testNetUserGetLocalGroups() { String currentUser = Secur32Util.getUserNameEx( EXTENDED_NAME_FORMAT.NameSamCompatible); @@ -106,48 +109,48 @@ IntByReference entriesread = new IntByReference(); IntByReference totalentries = new IntByReference(); assertEquals(LMErr.NERR_Success, Netapi32.INSTANCE.NetUserGetLocalGroups( - null, currentUser, 0, 0, bufptr, LMCons.MAX_PREFERRED_LENGTH, + null, currentUser, 0, 0, bufptr, LMCons.MAX_PREFERRED_LENGTH, entriesread, totalentries)); - LOCALGROUP_USERS_INFO_0 lgroup = new LOCALGROUP_USERS_INFO_0(bufptr.getValue()); + 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()); for (LOCALGROUP_USERS_INFO_0 localGroupInfo : lgroups) { assertTrue(localGroupInfo.lgrui0_name.length() > 0); } assertEquals(LMErr.NERR_Success, Netapi32.INSTANCE.NetApiBufferFree(bufptr.getValue())); - } - + } + public void testNetGroupEnum() { PointerByReference bufptr = new PointerByReference(); IntByReference entriesread = new IntByReference(); IntByReference totalentries = new IntByReference(); assertEquals(LMErr.NERR_Success, Netapi32.INSTANCE.NetGroupEnum( - null, 2, bufptr, LMCons.MAX_PREFERRED_LENGTH, entriesread, totalentries, null)); - GROUP_INFO_2 group = new GROUP_INFO_2(bufptr.getValue()); + null, 2, bufptr, LMCons.MAX_PREFERRED_LENGTH, entriesread, totalentries, null)); + GROUP_INFO_2 group = new GROUP_INFO_2(bufptr.getValue()); GROUP_INFO_2[] groups = (GROUP_INFO_2[]) group.toArray(entriesread.getValue()); for (GROUP_INFO_2 grpi : groups) { assertTrue(grpi.grpi2_name.length() > 0); } assertEquals(LMErr.NERR_Success, Netapi32.INSTANCE.NetApiBufferFree(bufptr.getValue())); } - + public void testNetUserEnum() { PointerByReference bufptr = new PointerByReference(); IntByReference entriesread = new IntByReference(); IntByReference totalentries = new IntByReference(); - assertEquals(LMErr.NERR_Success, Netapi32.INSTANCE.NetUserEnum( - null, 1, 0, bufptr, LMCons.MAX_PREFERRED_LENGTH, entriesread, totalentries, null)); - USER_INFO_1 userinfo = new USER_INFO_1(bufptr.getValue()); + assertEquals(LMErr.NERR_Success, Netapi32.INSTANCE.NetUserEnum( + null, 1, 0, bufptr, LMCons.MAX_PREFERRED_LENGTH, entriesread, totalentries, null)); + USER_INFO_1 userinfo = new USER_INFO_1(bufptr.getValue()); USER_INFO_1[] userinfos = (USER_INFO_1[]) userinfo.toArray(entriesread.getValue()); for (USER_INFO_1 ui : userinfos) { assertTrue(ui.usri1_name.length() > 0); } assertEquals(LMErr.NERR_Success, Netapi32.INSTANCE.NetApiBufferFree(bufptr.getValue())); - } - + } + public void testNetUserAdd() { USER_INFO_1 userInfo = new USER_INFO_1(); - userInfo.usri1_name = new WString("JNANetapi32TestUser"); - userInfo.usri1_password = new WString("!JNAP$$Wrd0"); + userInfo.usri1_name = "JNANetapi32TestUser"; + userInfo.usri1_password = "!JNAP$$Wrd0"; userInfo.usri1_priv = LMAccess.USER_PRIV_USER; // ignore test if not able to add user (need to be administrator to do this). if (LMErr.NERR_Success != Netapi32.INSTANCE.NetUserAdd(Kernel32Util.getComputerName(), 1, userInfo, null)) { @@ -156,11 +159,11 @@ assertEquals(LMErr.NERR_Success, Netapi32.INSTANCE.NetUserDel( Kernel32Util.getComputerName(), userInfo.usri1_name.toString())); } - + public void testNetUserChangePassword() { USER_INFO_1 userInfo = new USER_INFO_1(); - userInfo.usri1_name = new WString("JNANetapi32TestUser"); - userInfo.usri1_password = new WString("!JNAP$$Wrd0"); + userInfo.usri1_name = "JNANetapi32TestUser"; + userInfo.usri1_password = "!JNAP$$Wrd0"; userInfo.usri1_priv = LMAccess.USER_PRIV_USER; // ignore test if not able to add user (need to be administrator to do this). if (LMErr.NERR_Success != Netapi32.INSTANCE.NetUserAdd(Kernel32Util.getComputerName(), 1, userInfo, null)) { @@ -174,35 +177,35 @@ assertEquals(LMErr.NERR_Success, Netapi32.INSTANCE.NetUserDel( Kernel32Util.getComputerName(), userInfo.usri1_name.toString())); } - } - + } + public void testNetUserDel() { assertEquals(LMErr.NERR_UserNotFound, Netapi32.INSTANCE.NetUserDel( Kernel32Util.getComputerName(), "JNANetapi32TestUserDoesntExist")); } - + public void testDsGetDcName() { if (Netapi32Util.getJoinStatus() != LMJoin.NETSETUP_JOIN_STATUS.NetSetupDomainName) return; - + PDOMAIN_CONTROLLER_INFO.ByReference pdci = new PDOMAIN_CONTROLLER_INFO.ByReference(); assertEquals(W32Errors.ERROR_SUCCESS, Netapi32.INSTANCE.DsGetDcName( null, null, null, null, 0, pdci)); assertEquals(W32Errors.ERROR_SUCCESS, Netapi32.INSTANCE.NetApiBufferFree( pdci.getPointer())); } - + public void testDsGetForestTrustInformation() { if (Netapi32Util.getJoinStatus() != LMJoin.NETSETUP_JOIN_STATUS.NetSetupDomainName) return; - String domainController = Netapi32Util.getDCName(); + String domainController = Netapi32Util.getDCName(); PLSA_FOREST_TRUST_INFORMATION.ByReference pfti = new PLSA_FOREST_TRUST_INFORMATION.ByReference(); assertEquals(W32Errors.NO_ERROR, Netapi32.INSTANCE.DsGetForestTrustInformation( domainController, null, 0, pfti)); - + assertTrue(pfti.fti.RecordCount >= 0); - + for (PLSA_FOREST_TRUST_RECORD precord : pfti.fti.getEntries()) { LSA_FOREST_TRUST_RECORD.UNION data = precord.tr.u; switch(precord.tr.ForestTrustType) { @@ -227,22 +230,22 @@ break; } } - + assertEquals(W32Errors.ERROR_SUCCESS, Netapi32.INSTANCE.NetApiBufferFree( - pfti.getPointer())); + pfti.getPointer())); } - - + + public void testDsEnumerateDomainTrusts() { if (Netapi32Util.getJoinStatus() != LMJoin.NETSETUP_JOIN_STATUS.NetSetupDomainName) return; IntByReference domainTrustCount = new IntByReference(); PointerByReference domainsPointerRef = new PointerByReference(); - assertEquals(W32Errors.NO_ERROR, Netapi32.INSTANCE.DsEnumerateDomainTrusts(null, + assertEquals(W32Errors.NO_ERROR, Netapi32.INSTANCE.DsEnumerateDomainTrusts(null, DsGetDC.DS_DOMAIN_VALID_FLAGS, domainsPointerRef, domainTrustCount)); assertTrue(domainTrustCount.getValue() >= 0); - + DS_DOMAIN_TRUSTS domainTrustRefs = new DS_DOMAIN_TRUSTS(domainsPointerRef.getValue()); DS_DOMAIN_TRUSTS[] domainTrusts = (DS_DOMAIN_TRUSTS[]) domainTrustRefs.toArray(new DS_DOMAIN_TRUSTS[domainTrustCount.getValue()]); @@ -252,9 +255,103 @@ assertTrue(Advapi32Util.convertSidToStringSid(trust.DomainSid).startsWith("S-")); assertTrue(Ole32Util.getStringFromGUID(trust.DomainGuid).startsWith("{")); } - - assertEquals(W32Errors.ERROR_SUCCESS, Netapi32.INSTANCE.NetApiBufferFree(domainTrustRefs.getPointer())); + + assertEquals(W32Errors.ERROR_SUCCESS, Netapi32.INSTANCE.NetApiBufferFree(domainTrustRefs.getPointer())); } + public void testNetShareAddShareInfo2() throws Exception { + + File fileShareFolder = createTempFolder(); + + SHARE_INFO_2 shi = new SHARE_INFO_2(); + shi.shi2_netname = fileShareFolder.getName(); + shi.shi2_type = LMShare.STYPE_DISKTREE; + shi.shi2_remark = ""; + shi.shi2_permissions = LMAccess.ACCESS_ALL; + shi.shi2_max_uses = -1; + shi.shi2_current_uses = 0; + shi.shi2_path = fileShareFolder.getAbsolutePath(); + shi.shi2_passwd = ""; + + // Write from struct to native memory. + shi.write(); + + IntByReference parm_err = new IntByReference(0); + int winError = Netapi32.INSTANCE.NetShareAdd(null, // Use local computer + 2, shi.getPointer(), parm_err); + + if (winError == W32Errors.ERROR_INVALID_PARAMETER) { + // fail with offset. + throw new Exception("testNetShareAddShareInfo2 failed with invalid parameter on structure offset: " + parm_err.getValue()); + } + + assertEquals("Failed to add share", LMErr.NERR_Success, winError); + + Netapi32.INSTANCE.NetShareDel(null, shi.shi2_netname, 0); + } + + public void testNetShareAddShareInfo502() throws Exception { + + File fileShareFolder = createTempFolder(); + + SHARE_INFO_502 shi = new SHARE_INFO_502(); + shi.shi502_netname = fileShareFolder.getName(); + shi.shi502_type = LMShare.STYPE_DISKTREE; + shi.shi502_remark = ""; + shi.shi502_permissions = LMAccess.ACCESS_ALL; + shi.shi502_max_uses = -1; + shi.shi502_current_uses = 0; + shi.shi502_path = fileShareFolder.getAbsolutePath(); + shi.shi502_passwd = null; + shi.shi502_reserved = 0; + shi.shi502_security_descriptor = null; + + // Write from struct to native memory. + shi.write(); + + IntByReference parm_err = new IntByReference(0); + int winError = Netapi32.INSTANCE.NetShareAdd(null, // Use local computer + 502, shi.getPointer(), parm_err); + + if (winError == W32Errors.ERROR_INVALID_PARAMETER) { + // fail with offset. + throw new Exception("testNetShareAddShareInfo502 failed with invalid parameter on structure offset: " + parm_err.getValue()); + } + + assertEquals(LMErr.NERR_Success, winError); + + Netapi32.INSTANCE.NetShareDel(null, shi.shi502_netname, 0); + } + + public void testNetShareDel() throws Exception { + + File fileShareFolder = createTempFolder(); + + SHARE_INFO_2 shi = new SHARE_INFO_2(); + shi.shi2_netname = fileShareFolder.getName(); + shi.shi2_type = LMShare.STYPE_DISKTREE; + shi.shi2_remark = ""; + shi.shi2_permissions = LMAccess.ACCESS_ALL; + shi.shi2_max_uses = -1; + shi.shi2_current_uses = 0; + shi.shi2_path = fileShareFolder.getAbsolutePath(); + shi.shi2_passwd = ""; + + // Write from struct to native memory. + shi.write(); + + IntByReference parm_err = new IntByReference(0); + assertEquals("Failed to add share", LMErr.NERR_Success, Netapi32.INSTANCE.NetShareAdd(null, // Use local computer + 2, shi.getPointer(), parm_err)); + + assertEquals("Failed to delete share", LMErr.NERR_Success, Netapi32.INSTANCE.NetShareDel(null, shi.shi2_netname, 0)); + } + + private File createTempFolder() throws Exception { + String folderPath = System.getProperty("java.io.tmpdir") + File.separatorChar + System.nanoTime(); + File file = new File(folderPath); + file.mkdir(); + return file; + } } diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/Netapi32UtilTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/Netapi32UtilTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/Netapi32UtilTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/Netapi32UtilTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,14 @@ /* Copyright (c) 2010 Daniel Doubrovkine, All Rights Reserved - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * Lesser General Public License for more details. */ package com.sun.jna.platform.win32; @@ -61,24 +61,24 @@ System.out.println(" site: " + dc.clientSiteName); System.out.println(" forest: " + dc.dnsForestName); System.out.println(" guid: " + Ole32Util.getStringFromGUID(dc.domainGuid)); - } + } // domain trusts if (Netapi32Util.getJoinStatus() == LMJoin.NETSETUP_JOIN_STATUS.NetSetupDomainName) { DomainTrust[] trusts = Netapi32Util.getDomainTrusts(); System.out.println("Domain trusts: (" + trusts.length + ")"); for(DomainTrust trust : trusts) { - System.out.println(" " + trust.NetbiosDomainName + ": " + trust.DnsDomainName + System.out.println(" " + trust.NetbiosDomainName + ": " + trust.DnsDomainName + " (" + trust.DomainSidString + ")"); } } } - + public void testGetDomain() { String computerName = System.getenv("COMPUTERNAME"); String domain = Netapi32Util.getDomainName(computerName); assertTrue(domain.length() > 0); } - + public void testGetLocalGroups() { Netapi32Util.LocalGroup[] localGroups = Netapi32Util.getLocalGroups(); assertNotNull(localGroups); @@ -96,7 +96,7 @@ } assertTrue(users.length > 0); } - + public void testGetUserInfo() { if (Netapi32Util.getJoinStatus() != LMJoin.NETSETUP_JOIN_STATUS.NetSetupDomainName) return; @@ -104,12 +104,11 @@ } public void testGetUserInfoWithDomainSpecified() { - UserInfo userInfo = Netapi32Util.getUserInfo(Advapi32Util.getUserName(), - System.getenv("USERDOMAIN")); - assertNotNull(userInfo); - assertTrue(Advapi32.INSTANCE.IsValidSid(userInfo.sid)); + UserInfo userInfo = Netapi32Util.getUserInfo(Advapi32Util.getUserName(), System.getenv("USERDOMAIN")); + assertNotNull("No user info retrieved", userInfo); + assertTrue("Invalid user SID", Advapi32.INSTANCE.IsValidSid(userInfo.sid)); } - + public void testGetGlobalGroups() { Netapi32Util.Group[] groups = Netapi32Util.getGlobalGroups(); assertNotNull(groups); @@ -118,7 +117,7 @@ } assertTrue(groups.length > 0); } - + public void testGetCurrentUserLocalGroups() { Netapi32Util.Group[] localGroups = Netapi32Util.getCurrentUserLocalGroups(); assertNotNull(localGroups); @@ -134,25 +133,25 @@ || joinStatus == LMJoin.NETSETUP_JOIN_STATUS.NetSetupUnjoined || joinStatus == LMJoin.NETSETUP_JOIN_STATUS.NetSetupWorkgroupName); } - + public void testGetDCName() { if (Netapi32Util.getJoinStatus() != LMJoin.NETSETUP_JOIN_STATUS.NetSetupDomainName) return; - + String domainController = Netapi32Util.getDCName(); assertTrue(domainController.length() > 0); assertTrue(domainController.startsWith("\\\\")); } - + public void testGetDC() { if (Netapi32Util.getJoinStatus() != LMJoin.NETSETUP_JOIN_STATUS.NetSetupDomainName) return; - + DomainController dc = Netapi32Util.getDC(); - assertTrue(dc.address.startsWith("\\\\")); - assertTrue(dc.domainName.length() > 0); + assertTrue("Invalid address prefix: " + dc.address, dc.address.startsWith("\\\\")); + assertTrue("Empty domain name", dc.domainName.length() > 0); } - + public void testGetDomainTrusts() { if (Netapi32Util.getJoinStatus() != LMJoin.NETSETUP_JOIN_STATUS.NetSetupDomainName) return; diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/NtDllTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/NtDllTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/NtDllTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/NtDllTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -12,13 +12,22 @@ */ package com.sun.jna.platform.win32; -import junit.framework.TestCase; +import static com.sun.jna.platform.win32.WinNT.DACL_SECURITY_INFORMATION; +import static com.sun.jna.platform.win32.WinNT.GROUP_SECURITY_INFORMATION; +import static com.sun.jna.platform.win32.WinNT.OWNER_SECURITY_INFORMATION; + +import java.io.File; +import java.io.FileWriter; +import com.sun.jna.Memory; import com.sun.jna.platform.win32.Wdm.KEY_BASIC_INFORMATION; import com.sun.jna.platform.win32.Wdm.KEY_INFORMATION_CLASS; +import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.platform.win32.WinReg.HKEYByReference; import com.sun.jna.ptr.IntByReference; +import junit.framework.TestCase; + /** * @author dblock[at]dblock[dot]org */ @@ -44,8 +53,74 @@ phKey.getValue(), Wdm.KEY_INFORMATION_CLASS.KeyBasicInformation, keyInformation, resultLength.getValue(), resultLength)); // show - assertEquals("Software", keyInformation.getName()); + // Keys are case insensitive (https://msdn.microsoft.com/de-de/library/windows/desktop/ms724946(v=vs.85).aspx) + assertEquals("software", keyInformation.getName().toLowerCase()); // close key assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegCloseKey(phKey.getValue())); } + + public void testNtQuerySetSecurityObjectNoSACL() throws Exception { + int infoType = OWNER_SECURITY_INFORMATION + | GROUP_SECURITY_INFORMATION + | DACL_SECURITY_INFORMATION; + + // create a temp file + File file = createTempFile(); + String filePath = file.getAbsolutePath(); + HANDLE hFile = WinBase.INVALID_HANDLE_VALUE; + + try { + hFile = Kernel32.INSTANCE.CreateFile( + filePath, + WinNT.GENERIC_WRITE | WinNT.WRITE_OWNER | WinNT.WRITE_DAC, + WinNT.FILE_SHARE_READ, + new WinBase.SECURITY_ATTRIBUTES(), + WinNT.OPEN_EXISTING, + WinNT.FILE_ATTRIBUTE_NORMAL, + null); + assertFalse("Failed to create file handle: " + filePath, WinBase.INVALID_HANDLE_VALUE.equals(hFile)); + + int Length = 64 * 1024; + Memory SecurityDescriptor = new Memory(Length); + IntByReference LengthNeeded = new IntByReference(); + + assertEquals("NtQuerySecurityObject(" + filePath + ")", 0, + NtDll.INSTANCE.NtQuerySecurityObject( + hFile, + infoType, + SecurityDescriptor, + Length, + LengthNeeded)); + assertTrue(LengthNeeded.getValue() > 0); + assertTrue(LengthNeeded.getValue() < 64 * 1024); + assertEquals("NtSetSecurityObject(" + filePath + ")", 0, + NtDll.INSTANCE.NtSetSecurityObject( + hFile, + infoType, + SecurityDescriptor)); + } finally { + if (hFile != WinBase.INVALID_HANDLE_VALUE) + Kernel32.INSTANCE.CloseHandle(hFile); + file.delete(); + } + } + + public void testRtlNtStatusToDosError() { + int status = NTStatus.STATUS_INVALID_OWNER; + int error = NtDll.INSTANCE.RtlNtStatusToDosError(status); + assertEquals(W32Errors.ERROR_INVALID_OWNER, error); + } + + private File createTempFile() throws Exception { + String filePath = System.getProperty("java.io.tmpdir") + System.nanoTime() + + ".text"; + File file = new File(filePath); + file.createNewFile(); + FileWriter fileWriter = new FileWriter(file); + for (int i = 0; i < 1000; i++) { + fileWriter.write("Sample text " + i + System.getProperty("line.separator")); + } + fileWriter.close(); + return file; + } } diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/NtDllUtilTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/NtDllUtilTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/NtDllUtilTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/NtDllUtilTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -29,7 +29,8 @@ HKEYByReference phKey = new HKEYByReference(); assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegOpenKeyEx( WinReg.HKEY_CURRENT_USER, "Software", 0, WinNT.KEY_WRITE | WinNT.KEY_READ, phKey)); - assertEquals("Software", NtDllUtil.getKeyName(phKey.getValue())); + // Keys are case insensitive (https://msdn.microsoft.com/de-de/library/windows/desktop/ms724946(v=vs.85).aspx) + assertEquals("software", NtDllUtil.getKeyName(phKey.getValue()).toLowerCase()); assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegCloseKey(phKey.getValue())); } } diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/Ole32Test.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/Ole32Test.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/Ole32Test.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/Ole32Test.java 2017-03-14 19:31:03.000000000 +0000 @@ -16,9 +16,7 @@ import com.sun.jna.Native; import com.sun.jna.Pointer; -import com.sun.jna.platform.win32.BaseTSD.SIZE_T; import com.sun.jna.platform.win32.Guid.GUID; -import com.sun.jna.platform.win32.WinDef.LPVOID; import com.sun.jna.platform.win32.WinNT.HRESULT; import com.sun.jna.ptr.PointerByReference; diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/OleAutoTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/OleAutoTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/OleAutoTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/OleAutoTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -14,11 +14,8 @@ import junit.framework.TestCase; -import com.sun.jna.Native; import com.sun.jna.WString; import com.sun.jna.platform.win32.Guid.CLSID; -import com.sun.jna.platform.win32.OaIdl.SAFEARRAY; -import com.sun.jna.platform.win32.Variant.VARIANT; import com.sun.jna.platform.win32.WTypes.BSTR; import com.sun.jna.platform.win32.WinDef.LCID; import com.sun.jna.platform.win32.WinNT.HRESULT; @@ -30,47 +27,39 @@ */ public class OleAutoTest extends TestCase { - public static void main(String[] args) { - junit.textui.TestRunner.run(OleAutoTest.class); - } - - public OleAutoTest() { - } - - public void testSysAllocString() { - assertEquals(null, OleAuto.INSTANCE.SysAllocString(null)); - BSTR p = OleAuto.INSTANCE.SysAllocString("hello world"); - assertEquals("hello world", p.getValue()); - OleAuto.INSTANCE.SysFreeString(p); - } - - public void testSysFreeString() { - OleAuto.INSTANCE.SysFreeString(null); - } - - public void testDISPPARAMS() { - // Build DISPPARAMS - SAFEARRAY.ByReference safeArg = OleAutoUtil.createVarArray(1); - OleAutoUtil.SafeArrayPutElement(safeArg, 0, new VARIANT( - Variant.VARIANT_TRUE)); - //System.out.println(safeArg.toString(true)); - } - - public void testLoadRegTypeLib() { - CLSID.ByReference clsid = new CLSID.ByReference(); - // get CLSID from string, Microsoft Scripting Engine - HRESULT hr = Ole32.INSTANCE.CLSIDFromString(new WString( - "{420B2830-E718-11CF-893D-00A0C9054228}"), clsid); - COMUtils.checkRC(hr); - assertEquals(0, hr.intValue()); - - // get user default lcid - LCID lcid = Kernel32.INSTANCE.GetUserDefaultLCID(); - PointerByReference pWordTypeLib = new PointerByReference(); - // get typelib version 1.0 - hr = OleAuto.INSTANCE.LoadRegTypeLib(clsid, 1, 0, lcid, pWordTypeLib); - COMUtils.checkRC(hr); - assertEquals(0, hr.intValue()); - } + public static void main(String[] args) { + junit.textui.TestRunner.run(OleAutoTest.class); + } + + public OleAutoTest() { + } + + public void testSysAllocString() { + assertEquals(null, OleAuto.INSTANCE.SysAllocString(null)); + BSTR p = OleAuto.INSTANCE.SysAllocString("hello world"); + assertEquals("hello world", p.getValue()); + OleAuto.INSTANCE.SysFreeString(p); + } + + public void testSysFreeString() { + OleAuto.INSTANCE.SysFreeString(null); + } + + public void testLoadRegTypeLib() { + CLSID.ByReference clsid = new CLSID.ByReference(); + // get CLSID from string, Microsoft Scripting Engine + HRESULT hr = Ole32.INSTANCE.CLSIDFromString(new WString( + "{420B2830-E718-11CF-893D-00A0C9054228}"), clsid); + COMUtils.checkRC(hr); + assertEquals(0, hr.intValue()); + + // get user default lcid + LCID lcid = Kernel32.INSTANCE.GetUserDefaultLCID(); + PointerByReference pWordTypeLib = new PointerByReference(); + // get typelib version 1.0 + hr = OleAuto.INSTANCE.LoadRegTypeLib(clsid, 1, 0, lcid, pWordTypeLib); + COMUtils.checkRC(hr); + assertEquals(0, hr.intValue()); + } } diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/OleAutoUtilTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/OleAutoUtilTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/OleAutoUtilTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/OleAutoUtilTest.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ -/* Copyright (c) 2013 Tobias Wolf, All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform.win32; - -import junit.framework.TestCase; - -import com.sun.jna.platform.win32.OaIdl.SAFEARRAY; -import com.sun.jna.platform.win32.Variant.VARIANT; -import com.sun.jna.platform.win32.WinDef.SHORT; -import com.sun.jna.platform.win32.COM.COMException; - -/** - * @author Tobias Wolf, wolf.tobias@gmx.net - */ -public class OleAutoUtilTest extends TestCase { - - public static void main(String[] args) { - junit.textui.TestRunner.run(OleAutoUtilTest.class); - } - - public void testCreateVarArray() { - SAFEARRAY varArray = OleAutoUtil.createVarArray(1); - assertTrue(varArray != null); - } - - public void testSafeArrayPutGetElement() throws Exception { - SAFEARRAY varArray = OleAutoUtil.createVarArray(10); - - for (int i = 0; i < 10; i++) { - VARIANT variant = new VARIANT(new SHORT(i + i*100)); - //System.out.println(variant.toString(true)); - OleAutoUtil.SafeArrayPutElement(varArray, i, variant); - } - - assertTrue(varArray != null); - - for (int i = 0; i < 10; i++) { - VARIANT element = OleAutoUtil.SafeArrayGetElement(varArray, i); - /* - System.out.println(element.toString(true)); - System.out.println("variant type: " + element.getVarType()); - System.out.println("value: " + element.getValue()); - */ - } - } -} diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/PdhTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/PdhTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/PdhTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/PdhTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -48,7 +48,7 @@ HANDLE hQuery = ref.getValue(); try { ref.setValue(null); - assertErrorSuccess("PdhAddCounter", pdh.PdhAddCounter(hQuery, counterName, null, ref), true); + assertErrorSuccess("PdhAddEnglishCounter", pdh.PdhAddEnglishCounter(hQuery, counterName, null, ref), true); HANDLE hCounter = ref.getValue(); try { @@ -93,7 +93,7 @@ try { for (String counterName : names) { ref.setValue(null); - assertErrorSuccess("PdhAddCounter[" + counterName + "]", pdh.PdhAddCounter(hQuery, counterName, null, ref), true); + assertErrorSuccess("PdhAddCounter[" + counterName + "]", pdh.PdhAddEnglishCounter(hQuery, counterName, null, ref), true); HANDLE hCounter = ref.getValue(); handlesMap.put(counterName, hCounter); diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/PsapiTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/PsapiTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/PsapiTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/PsapiTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,32 +1,39 @@ /* Copyright (c) 2015 Andreas "PAX" L\u00FCck, All Rights Reserved - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * Lesser General Public License for more details. */ package com.sun.jna.platform.win32; import static org.junit.Assert.assertTrue; +import java.util.LinkedList; +import java.util.List; + import javax.swing.JFrame; import org.junit.Test; import com.sun.jna.Memory; import com.sun.jna.Native; +import com.sun.jna.platform.win32.Psapi.MODULEINFO; +import com.sun.jna.platform.win32.Psapi.PERFORMANCE_INFORMATION; +import com.sun.jna.platform.win32.WinDef.DWORD; +import com.sun.jna.platform.win32.WinDef.HMODULE; import com.sun.jna.platform.win32.WinDef.HWND; import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.ptr.IntByReference; /** * Applies API tests on {@link Psapi}. - * + * * @author Andreas "PAX" Lück, onkelpax-git[at]yahoo.de */ public class PsapiTest { @@ -94,4 +101,136 @@ w.dispose(); } } + + @Test + public void testEnumProcessModules() { + HANDLE me = null; + Win32Exception we = null; + + try { + 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(); + + HMODULE[] lphModule = new HMODULE[100 * 4]; + IntByReference lpcbNeeded = new IntByReference(); + + if (!Psapi.INSTANCE.EnumProcessModules(me, lphModule, lphModule.length, lpcbNeeded)) { + throw new Win32Exception(Native.getLastError()); + } + + for (int i = 0; i < lpcbNeeded.getValue() / 4; i++) { + list.add(lphModule[i]); + } + + assertTrue("List should have at least 1 item in it.", list.size() > 0); + } catch (Win32Exception e) { + we = e; + throw we; // re-throw to invoke finally block + } finally { + try { + Kernel32Util.closeHandle(me); + } catch(Win32Exception e) { + if (we == null) { + we = e; + } else { + we.addSuppressed(e); + } + } + if (we != null) { + throw we; + } + } + } + + @Test + public void testGetModuleInformation() { + HANDLE me = null; + Win32Exception we = null; + + try { + 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(); + + HMODULE[] lphModule = new HMODULE[100 * 4]; + IntByReference lpcbNeeded = new IntByReference(); + + if (!Psapi.INSTANCE.EnumProcessModules(me, lphModule, lphModule.length, lpcbNeeded)) { + throw new Win32Exception(Native.getLastError()); + } + + for (int i = 0; i < lpcbNeeded.getValue() / 4; i++) { + list.add(lphModule[i]); + } + + assertTrue("List should have at least 1 item in it.", list.size() > 0); + + MODULEINFO lpmodinfo = new MODULEINFO(); + + if (!Psapi.INSTANCE.GetModuleInformation(me, list.get(0), lpmodinfo, lpmodinfo.size())) { + throw new Win32Exception(Native.getLastError()); + } + + assertTrue("MODULEINFO.EntryPoint should not be null.", lpmodinfo.EntryPoint != null); + + } catch (Win32Exception e) { + we = e; + throw we; // re-throw to invoke finally block + } finally { + try { + Kernel32Util.closeHandle(me); + } catch(Win32Exception e) { + if (we == null) { + we = e; + } else { + we.addSuppressed(e); + } + } + if (we != null) { + throw we; + } + } + } + + @Test + public void testGetProcessImageFileName() { + HANDLE me = null; + Win32Exception we = null; + + try { + me = Kernel32.INSTANCE.OpenProcess(WinNT.PROCESS_ALL_ACCESS, false, Kernel32.INSTANCE.GetCurrentProcessId()); + assertTrue("Handle to my process should not be null", me != null); + + char[] buffer = new char[256]; + Psapi.INSTANCE.GetProcessImageFileName(me, buffer, 256); + String path = new String(buffer); + assertTrue("Image path should contain 'java' and '.exe'", path.contains("java") && path.contains(".exe")); + } catch (Win32Exception e) { + we = e; + throw we; // re-throw to invoke finally block + } finally { + try { + Kernel32Util.closeHandle(me); + } catch(Win32Exception e) { + if (we == null) { + we = e; + } else { + we.addSuppressed(e); + } + } + if (we != null) { + throw we; + } + } + } + + @Test + public void testGetPerformanceInfo() { + PERFORMANCE_INFORMATION perfInfo = new PERFORMANCE_INFORMATION(); + assertTrue(Psapi.INSTANCE.GetPerformanceInfo(perfInfo, perfInfo.size())); + assertTrue(perfInfo.ProcessCount.intValue() > 0); + } } diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/Rasapi32Test.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/Rasapi32Test.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/Rasapi32Test.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/Rasapi32Test.java 2017-03-14 19:31:03.000000000 +0000 @@ -42,7 +42,11 @@ assertEquals(W32Errors.ERROR_SUCCESS, Rasapi32.INSTANCE.RasGetErrorString(632, msg, msg.length)); int len = 0; for (; len < msg.length; len++) if (msg[len] == 0) break; - assertEquals("An incorrect structure size was detected.", new String (msg, 0, len)); + if(AbstractWin32TestSupport.isEnglishLocale) { + assertEquals("An incorrect structure size was detected.", new String (msg, 0, len)); + } else { + System.err.println("testRasGetErrorString test can only be run with english locale."); + } } public void testRasGetCredentials() { diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/Rasapi32UtilTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/Rasapi32UtilTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/Rasapi32UtilTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/Rasapi32UtilTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -55,7 +55,11 @@ } public void testGetRasErrorString() { - assertEquals("An incorrect structure size was detected.", Rasapi32Util.getRasErrorString(632)); + if(AbstractWin32TestSupport.isEnglishLocale) { + assertEquals("An incorrect structure size was detected.", Rasapi32Util.getRasErrorString(632)); + } else { + System.err.println("testGetRasErrorString test can only be run with english locale."); + } } public void testGetRasConnectionStatusText() { diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/SAFEARRAYTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/SAFEARRAYTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/SAFEARRAYTest.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/SAFEARRAYTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,834 @@ +/* Copyright (c) 2013 Tobias Wolf, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ +package com.sun.jna.platform.win32; + +import com.sun.jna.Pointer; +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; +import com.sun.jna.platform.win32.COM.util.IComEnum; +import com.sun.jna.platform.win32.COM.util.IConnectionPoint; +import com.sun.jna.platform.win32.COM.util.IUnknown; +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; +import com.sun.jna.platform.win32.COM.util.annotation.ComProperty; +import com.sun.jna.platform.win32.OaIdl.DATE; +import com.sun.jna.platform.win32.OaIdl.SAFEARRAY; +import static com.sun.jna.platform.win32.OaIdlUtil.toPrimitiveArray; +import com.sun.jna.platform.win32.Variant.VARIANT; +import static com.sun.jna.platform.win32.Variant.VT_BOOL; +import static com.sun.jna.platform.win32.Variant.VT_BSTR; +import static com.sun.jna.platform.win32.Variant.VT_DATE; +import static com.sun.jna.platform.win32.Variant.VT_ERROR; +import static com.sun.jna.platform.win32.Variant.VT_I1; +import static com.sun.jna.platform.win32.Variant.VT_I2; +import static com.sun.jna.platform.win32.Variant.VT_I4; +import static com.sun.jna.platform.win32.Variant.VT_INT; +import static com.sun.jna.platform.win32.Variant.VT_R4; +import static com.sun.jna.platform.win32.Variant.VT_R8; +import static com.sun.jna.platform.win32.Variant.VT_UI1; +import static com.sun.jna.platform.win32.Variant.VT_UI2; +import static com.sun.jna.platform.win32.Variant.VT_UI4; +import static com.sun.jna.platform.win32.Variant.VT_UINT; +import com.sun.jna.platform.win32.WTypes.BSTR; +import com.sun.jna.platform.win32.WinDef.LONGByReference; +import com.sun.jna.platform.win32.WinDef.SCODE; +import com.sun.jna.platform.win32.WinDef.UINT; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; +import static junit.framework.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; + +public class SAFEARRAYTest { + static { + ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true); + } + + @Before + public void setup() { + Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED); + } + + @After + public void teardown() { + Ole32.INSTANCE.CoUninitialize(); + } + + @Test + public void testCreateVarArray() { + SAFEARRAY varArray = SAFEARRAY.createSafeArray(1); + Assert.assertTrue(varArray != null); + } + + @Test + public void testSafeArrayPutGetElement() throws Exception { + int rowCount = 2; + int colCount = 10; + + SAFEARRAY varArray = SAFEARRAY.createSafeArray(rowCount, colCount); + + assertThat(varArray.getDimensionCount(), is(2)); + + assertThat(varArray.getUBound(0), equalTo(rowCount - 1)); + assertThat(varArray.getUBound(1), equalTo(colCount - 1)); + + for (int rowIdx = 0; rowIdx < rowCount; rowIdx++) { + for (int colIdx = 0; colIdx < colCount; colIdx++) { + VARIANT variant = new VARIANT(rowIdx + "#" + colIdx); + varArray.putElement(variant, rowIdx, colIdx); + } + } + + for (int rowIdx = 0; rowIdx < rowCount; rowIdx++) { + for (int colIdx = 0; colIdx < colCount; colIdx++) { + VARIANT element = (VARIANT) varArray.getElement(rowIdx, colIdx); + assertEquals(rowIdx + "#" + colIdx, element.stringValue()); + OleAuto.INSTANCE.VariantClear(element); + } + } + } + + @Ignore("Only for live testing") + @Test + public void testPerformance() { + ObjectFactory fact = new ObjectFactory(); + + // Open a record set with a sample search (basicly get the first five + // entries from the search index + Connection conn = fact.createObject(Connection.class); + conn.Open("Provider=Search.CollatorDSO;Extended Properties='Application=Windows';", "", "", -1); + + Recordset recordset = fact.createObject(Recordset.class); + recordset.Open("SELECT TOP 500 System.ItemPathDisplay, System.ItemName, System.ItemUrl, System.DateCreated FROM SYSTEMINDEX ORDER BY System.ItemUrl", conn, CursorTypeEnum.adOpenUnspecified, LockTypeEnum.adLockUnspecified, -1); + + SAFEARRAY wrap = recordset.GetRows(); + + assertThat(wrap.getDimensionCount(), is(2)); + + long timeDirect = 0; + long timeGetElement = 0; + long timePointer = 0; + long timeHelper = 0; + + long start, end; + + for (int i = 0; i < 4 * 10; i++) { + if (i % 4 == 0) { + start = System.currentTimeMillis(); + toArrayPtrToElement(wrap); + end = System.currentTimeMillis(); + timePointer += (end - start); + } else if (i % 4 == 1) { + start = System.currentTimeMillis(); + toArrayGetElement(wrap); + end = System.currentTimeMillis(); + timeGetElement += (end - start); + } else if (i % 4 == 2) { + start = System.currentTimeMillis(); + toArrayDirect(wrap); + end = System.currentTimeMillis(); + timeDirect += (end - start); + } else if (i % 4 == 3) { + start = System.currentTimeMillis(); + OaIdlUtil.toPrimitiveArray(wrap, false); + end = System.currentTimeMillis(); + timeHelper += (end - start); + } + } + + System.out.println("Direct: " + timeDirect + " ms"); + System.out.println("GetElement: " + timeGetElement + " ms"); + System.out.println("Pointer: " + timePointer + " ms"); + System.out.println("Helper: " + timeHelper + " ms"); + + recordset.Close(); + conn.Close(); + + fact.disposeAll(); + } + + private Object[] toArrayGetElement(SAFEARRAY wrap) { + wrap.lock(); + int rowMax = wrap.getUBound(2); + int columnMax = wrap.getUBound(1); + Object[][] result = new Object[(int) (rowMax + 1)][(int) (columnMax + 1)]; + for(int i = 0; i <= rowMax; i++) { + for(int j = 0; j <= columnMax; j++) { + VARIANT cell = (VARIANT) wrap.getElement(i, j); + result[(int)i][(int) j] = cell.getValue(); + OleAuto.INSTANCE.VariantClear(cell); + } + } + wrap.unlock(); + return result; + } + + private Object[] toArrayPtrToElement(SAFEARRAY wrap) { + wrap.lock(); + int rowMax = wrap.getUBound(2); + int columnMax = wrap.getUBound(1); + Object[][] result = new Object[(int) (rowMax + 1)][(int) (columnMax + 1)]; + for(int i = 0; i <= rowMax; i++) { + for(int j = 0; j <= columnMax; j++) { + VARIANT cell = new VARIANT(wrap.ptrOfIndex(i, j)); + result[(int)i][(int) j] = cell.getValue(); + } + } + wrap.unlock(); + return result; + } + + private Object[] toArrayDirect(SAFEARRAY wrap) { + Pointer dataPointer = wrap.accessData(); + long rowMax = wrap.getUBound(2); + long columnMax = wrap.getUBound(1); + VARIANT[] variantData = (VARIANT[]) new VARIANT(dataPointer).toArray((int) ((rowMax + 1) * (columnMax + 1))); + Object[][] result = new Object[(int) (rowMax + 1)][(int) (columnMax + 1)]; + for(long i = 0; i <= rowMax; i++) { + long rowOffset = i * columnMax; + for(long j = 0; j <= columnMax; j++) { + VARIANT cell = variantData[(int) (rowOffset + j)]; + result[(int)i][(int) j] = cell.getValue(); + } + } + wrap.unaccessData(); + return result; + } + + @Test + public void testDataTypes() { + int idx = 1; + Pointer dataPointer; + SAFEARRAY sa; + long elementSize; + + Object[] objectResult; + + sa = SAFEARRAY.createSafeArray(new WTypes.VARTYPE(VT_BOOL), 2); + elementSize = sa.getElemsize(); + assertThat(elementSize, equalTo(2L)); + dataPointer = sa.accessData(); + sa.putElement(true, idx); + short[] shortResult = dataPointer.getShortArray(0, 2); + objectResult = (Object[]) toPrimitiveArray(sa, false); + assertThat((Boolean) sa.getElement(idx), equalTo(true)); + assertThat(shortResult[idx], equalTo((short) 0xFFFF)); + assertThat((Short) dataPointer.getShort(idx * elementSize), equalTo((short) 0xFFFF)); + assertThat((Boolean) objectResult[idx], equalTo(true)); + sa.unaccessData(); + sa.destroy(); + + byte testByte = 67; + sa = SAFEARRAY.createSafeArray(new WTypes.VARTYPE(VT_UI1), 2); + elementSize = sa.getElemsize(); + assertThat(elementSize, equalTo(1L)); + dataPointer = sa.accessData(); + sa.putElement(testByte, idx); + byte[] byteResult = dataPointer.getByteArray(0, 2); + objectResult = (Object[]) toPrimitiveArray(sa, false); + assertThat((Byte) sa.getElement(idx), equalTo(testByte)); + assertThat(dataPointer.getByte(idx * elementSize), equalTo(testByte)); + assertThat(byteResult[idx], equalTo(testByte)); + assertThat((Byte) objectResult[idx], equalTo(testByte)); + sa.unaccessData(); + sa.destroy(); + + sa = SAFEARRAY.createSafeArray(new WTypes.VARTYPE(VT_I1), 2); + elementSize = sa.getElemsize(); + assertThat(elementSize, equalTo(1L)); + dataPointer = sa.accessData(); + sa.putElement(testByte, idx); + byteResult = dataPointer.getByteArray(0, 2); + objectResult = (Object[]) toPrimitiveArray(sa, false); + assertThat((Byte) sa.getElement(idx), equalTo(testByte)); + assertThat(dataPointer.getByte(idx * elementSize), equalTo(testByte)); + assertThat(byteResult[idx], equalTo(testByte)); + assertThat((Byte) objectResult[idx], equalTo(testByte)); + sa.unaccessData(); + sa.destroy(); + + short testShort = Short.MAX_VALUE - 1; + sa = SAFEARRAY.createSafeArray(new WTypes.VARTYPE(VT_UI2), 2); + elementSize = sa.getElemsize(); + assertThat(elementSize, equalTo(2L)); + dataPointer = sa.accessData(); + sa.putElement(testShort, idx); + shortResult = dataPointer.getShortArray(0, 2); + objectResult = (Object[]) toPrimitiveArray(sa, false); + assertThat((Short) sa.getElement(idx), equalTo(testShort)); + assertThat(dataPointer.getShort(idx * elementSize), equalTo(testShort)); + assertThat(shortResult[idx], equalTo(testShort)); + assertThat((Short) objectResult[idx], equalTo(testShort)); + sa.unaccessData(); + sa.destroy(); + + sa = SAFEARRAY.createSafeArray(new WTypes.VARTYPE(VT_I2), 2); + elementSize = sa.getElemsize(); + assertThat(elementSize, equalTo(2L)); + dataPointer = sa.accessData(); + sa.putElement(testShort, idx); + shortResult = dataPointer.getShortArray(0, 2); + objectResult = (Object[]) toPrimitiveArray(sa, false); + assertThat((Short) sa.getElement(idx), equalTo(testShort)); + assertThat(dataPointer.getShort(idx * elementSize), equalTo(testShort)); + assertThat(shortResult[idx], equalTo(testShort)); + assertThat((Short) objectResult[idx], equalTo(testShort)); + sa.unaccessData(); + sa.destroy(); + + int testInt = Integer.MAX_VALUE - 1; + sa = SAFEARRAY.createSafeArray(new WTypes.VARTYPE(VT_UI4), 2); + elementSize = sa.getElemsize(); + assertThat(elementSize, equalTo(4L)); + dataPointer = sa.accessData(); + sa.putElement(testInt, idx); + int[] intResult = dataPointer.getIntArray(0, 2); + objectResult = (Object[]) toPrimitiveArray(sa, false); + assertThat((Integer) sa.getElement(idx), equalTo(testInt)); + assertThat(dataPointer.getInt(idx * elementSize), equalTo(testInt)); + assertThat(intResult[idx], equalTo(testInt)); + assertThat((Integer) objectResult[idx], equalTo(testInt)); + sa.unaccessData(); + sa.destroy(); + + sa = SAFEARRAY.createSafeArray(new WTypes.VARTYPE(VT_I4), 2); + elementSize = sa.getElemsize(); + assertThat(elementSize, equalTo(4L)); + dataPointer = sa.accessData(); + sa.putElement(testInt, idx); + intResult = dataPointer.getIntArray(0, 2); + objectResult = (Object[]) toPrimitiveArray(sa, false); + assertThat((Integer) sa.getElement(idx), equalTo(testInt)); + assertThat(dataPointer.getInt(idx * elementSize), equalTo(testInt)); + assertThat(intResult[idx], equalTo(testInt)); + assertThat((Integer) objectResult[idx], equalTo(testInt)); + sa.unaccessData(); + sa.destroy(); + + sa = SAFEARRAY.createSafeArray(new WTypes.VARTYPE(VT_UINT), 2); + elementSize = sa.getElemsize(); + assertThat(elementSize, equalTo(4L)); + dataPointer = sa.accessData(); + sa.putElement(testInt, idx); + intResult = dataPointer.getIntArray(0, 2); + objectResult = (Object[]) toPrimitiveArray(sa, false); + assertThat((Integer) sa.getElement(idx), equalTo(testInt)); + assertThat(dataPointer.getInt(idx * elementSize), equalTo(testInt)); + assertThat(intResult[idx], equalTo(testInt)); + assertThat((Integer) objectResult[idx], equalTo(testInt)); + sa.unaccessData(); + sa.destroy(); + + sa = SAFEARRAY.createSafeArray(new WTypes.VARTYPE(VT_INT), 2); + elementSize = sa.getElemsize(); + assertThat(elementSize, equalTo(4L)); + dataPointer = sa.accessData(); + sa.putElement(testInt, idx); + intResult = dataPointer.getIntArray(0, 2); + objectResult = (Object[]) toPrimitiveArray(sa, false); + assertThat((Integer) sa.getElement(idx), equalTo(testInt)); + assertThat(dataPointer.getInt(idx * elementSize), equalTo(testInt)); + assertThat(intResult[idx], equalTo(testInt)); + assertThat((Integer) objectResult[idx], equalTo(testInt)); + sa.unaccessData(); + sa.destroy(); + + SCODE testSCODE = new SCODE(47); + sa = SAFEARRAY.createSafeArray(new WTypes.VARTYPE(VT_ERROR), 2); + elementSize = sa.getElemsize(); + assertThat(elementSize, equalTo(4L)); + dataPointer = sa.accessData(); + sa.putElement(testSCODE, idx); + intResult = dataPointer.getIntArray(0, 2); + objectResult = (Object[]) toPrimitiveArray(sa, false); + assertThat((SCODE) sa.getElement(idx), equalTo(testSCODE)); + assertThat(dataPointer.getInt(idx * elementSize), equalTo(47)); + assertThat(intResult[idx], equalTo(47)); + assertThat((SCODE) objectResult[idx], equalTo(testSCODE)); + sa.unaccessData(); + sa.destroy(); + + float testFloat = 42.23f; + sa = SAFEARRAY.createSafeArray(new WTypes.VARTYPE(VT_R4), 2); + elementSize = sa.getElemsize(); + assertThat(elementSize, equalTo(4L)); + dataPointer = sa.accessData(); + sa.putElement(testFloat, idx); + float[] floatResult = dataPointer.getFloatArray(0, 2); + objectResult = (Object[]) toPrimitiveArray(sa, false); + assertThat((Float) sa.getElement(idx), equalTo(testFloat)); + assertThat((Float) dataPointer.getFloat(idx * elementSize), equalTo(testFloat)); + assertThat(floatResult[idx], equalTo(testFloat)); + assertThat((Float) objectResult[idx], equalTo(testFloat)); + sa.unaccessData(); + sa.destroy(); + + double testDouble = 42.23d; + sa = SAFEARRAY.createSafeArray(new WTypes.VARTYPE(VT_R8), 2); + elementSize = sa.getElemsize(); + assertThat(elementSize, equalTo(8L)); + dataPointer = sa.accessData(); + sa.putElement(testDouble, idx); + double[] doubleResult = dataPointer.getDoubleArray(0, 2); + objectResult = (Object[]) toPrimitiveArray(sa, false); + assertThat((Double) sa.getElement(idx), equalTo(testDouble)); + assertThat((Double) dataPointer.getDouble(idx * elementSize), equalTo(testDouble)); + assertThat(doubleResult[idx], equalTo(testDouble)); + assertThat((Double) objectResult[idx], equalTo(testDouble)); + sa.unaccessData(); + sa.destroy(); + + Date testDate = new Date(1923, 1, 1, 5, 0, 0); + DATE testDATE = new DATE(testDate); + sa = SAFEARRAY.createSafeArray(new WTypes.VARTYPE(VT_DATE), 2); + elementSize = sa.getElemsize(); + assertThat(elementSize, equalTo(8L)); + dataPointer = sa.accessData(); + sa.putElement(testDATE, idx); + doubleResult = dataPointer.getDoubleArray(0, 2); + objectResult = (Object[]) toPrimitiveArray(sa, false); + assertThat(((DATE) sa.getElement(idx)).date, equalTo(testDATE.date)); + assertThat((Double) dataPointer.getDouble(idx * elementSize), equalTo(testDATE.date)); + assertThat(((DATE) sa.getElement(idx)).getAsJavaDate(), equalTo(testDate)); + assertThat(doubleResult[idx], equalTo(testDATE.date)); + assertThat((Date) objectResult[idx], equalTo(testDate)); + sa.unaccessData(); + sa.destroy(); + + String testString = "äöüßAE!"; + sa = SAFEARRAY.createSafeArray(new WTypes.VARTYPE(VT_BSTR), 2); + elementSize = sa.getElemsize(); + dataPointer = sa.accessData(); + sa.putElement(testString, idx); + Pointer[] pointerResult = dataPointer.getPointerArray(0, 2); + objectResult = (Object[]) toPrimitiveArray(sa, false); + assertThat(((String) sa.getElement(idx)), equalTo(testString)); + assertThat(new BSTR(dataPointer.getPointer(idx * elementSize)).getValue(), equalTo(testString)); + assertThat(new BSTR(pointerResult[idx]).getValue(), equalTo(testString)); + assertThat((String) objectResult[idx], equalTo(testString)); + sa.unaccessData(); + sa.destroy(); + + // VT_VARIANT is tested in testADODB + + // untested: VT_UNKNOWN + // untested: VT_DISPATCH + // untested: VT_CY + // untested: VT_DECIMAL + // unsupported: VT_RECORD + } + + + /** + * Test assumption: The windows search provider is present and holds at least + * five entries. If this assumption is not met, this test fails. + */ + @Test + public void testADODB() { + ObjectFactory fact = new ObjectFactory(); + + // Open a record set with a sample search (basicly get the first five + // entries from the search index + Connection conn = fact.createObject(Connection.class); + conn.Open("Provider=Search.CollatorDSO;Extended Properties='Application=Windows';", "", "", -1); + + Recordset recordset = fact.createObject(Recordset.class); + 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); + + while (!recordset.getEOF()) { + WinNT.HRESULT hr; + + // Fetch (all) five rows and extract SAFEARRAY + SAFEARRAY sa = recordset.GetRows(5); + + assertThat(sa.getDimensionCount(), is(2)); + + // Test getting bounds via automation functions SafeArrayGetLBound + // and SafeArrayGetUBound + + // 5 rows (dimension 1) and 4 (dimension 2) columns should be + // returned, the indices are zero-based, the lower bounds are + // always zero + // + // Dimensions are inverted between SafeArray and java, so + // in this case row dimension 2 retrieves row count, + // dimension 1 retrieves column count + WinDef.LONGByReference res = new WinDef.LONGByReference(); + + hr = OleAuto.INSTANCE.SafeArrayGetLBound(sa, new UINT(2), res); + assert COMUtils.SUCCEEDED(hr); + assertThat(res.getValue().intValue(), is(0)); + + hr = OleAuto.INSTANCE.SafeArrayGetUBound(sa, new UINT(2), res); + assert COMUtils.SUCCEEDED(hr); + assertThat(res.getValue().intValue(), is(4)); + + hr = OleAuto.INSTANCE.SafeArrayGetLBound(sa, new UINT(1), res); + assert COMUtils.SUCCEEDED(hr); + assertThat(res.getValue().intValue(), is(0)); + + hr = OleAuto.INSTANCE.SafeArrayGetUBound(sa, new UINT(1), res); + assert COMUtils.SUCCEEDED(hr); + assertThat(res.getValue().intValue(), is(3)); + + // Get dimensions directly from structure + // lLbound contains lowerBound (first index) + // cElements contains count of elements + int row_lower = sa.rgsabound[0].lLbound.intValue(); + int row_count = sa.rgsabound[0].cElements.intValue(); + int column_lower = sa.rgsabound[1].lLbound.intValue(); + int column_count = sa.rgsabound[1].cElements.intValue(); + assertThat(row_lower, is(0)); + assertThat(row_count, is(5)); + assertThat(column_lower, is(0)); + assertThat(column_count, is(4)); + + // Use Wrapper methods + assertThat(sa.getLBound(0), is(0)); + assertThat(sa.getUBound(0), is(4)); + assertThat(sa.getLBound(1), is(0)); + assertThat(sa.getUBound(1), is(3)); + + // Iterate over resultset and fetch via SafeArrayGetElement + // Columns 1 - 3 return Strings, Column 4 returns a date + for (int rowIdx = row_lower; rowIdx < row_lower + row_count; rowIdx++) { + for (int colIdx = column_lower; colIdx < column_lower + column_count; colIdx++) { + VARIANT result = (VARIANT) sa.getElement(rowIdx, colIdx); + Pointer pv = sa.ptrOfIndex(rowIdx, colIdx); + VARIANT result2 = new VARIANT(pv); + COMUtils.checkRC(hr); + if(colIdx == 3) { + assert (result.getVarType().intValue() & Variant.VT_DATE) > 0; + assert (result2.getVarType().intValue() & Variant.VT_DATE) > 0; + } else { + assert (result.getVarType().intValue() & Variant.VT_BSTR) > 0; + assert (result2.getVarType().intValue() & Variant.VT_BSTR) > 0; + } + // Only clear result, as SafeArrayGetElement creates a copy + // result2 is a view into the SafeArray + OleAuto.INSTANCE.VariantClear(result); + } + } + + // Access SafeArray directly + sa.lock(); + try { + // Map the returned array to java + VARIANT[] variantArray = (VARIANT[]) (new VARIANT(sa.pvData.getPointer()).toArray(row_count * column_count)); + + for (int rowIdx = 0; rowIdx < row_count; rowIdx++) { + for (int colIdx = 0; colIdx < column_count; colIdx++) { + int index = rowIdx * column_count + colIdx; + VARIANT result = variantArray[index]; + if (colIdx == 3) { + assert (result.getVarType().intValue() & Variant.VT_DATE) > 0; + } else { + assert (result.getVarType().intValue() & Variant.VT_BSTR) > 0; + } + // see comment for urls + if(colIdx == 2) { + urls.add(result.stringValue()); + } else if (colIdx == 1) { + names.add(result.stringValue()); + } + } + } + } finally { + sa.unlock(); + } + + // Access SafeArray directly - Variant 2 + Pointer data = sa.accessData(); + try { + // Map the returned array to java + VARIANT[] variantArray = (VARIANT[]) (new VARIANT(data).toArray(row_count * column_count)); + + for (int rowIdx = 0; rowIdx < row_count; rowIdx++) { + for (int colIdx = 0; colIdx < column_count; colIdx++) { + int index = rowIdx * column_count + colIdx; + VARIANT result = variantArray[index]; + if (colIdx == 3) { + assert (result.getVarType().intValue() & Variant.VT_DATE) > 0; + } else { + assert (result.getVarType().intValue() & Variant.VT_BSTR) > 0; + } + // see comment for urls + if(colIdx == 2) { + urls.add(result.stringValue()); + } else if (colIdx == 1) { + names.add(result.stringValue()); + } + } + } + } finally { + sa.unaccessData(); + } + + sa.destroy(); + } + + recordset.Close(); + + // Requery and fetch only columns "System.ItemUrl", "System.ItemName" and "System.ItemUrl" + recordset = fact.createObject(Recordset.class); + recordset.Open("SELECT TOP 5 System.ItemPathDisplay, System.ItemName, System.ItemUrl FROM SYSTEMINDEX ORDER BY System.ItemUrl", conn, CursorTypeEnum.adOpenUnspecified, LockTypeEnum.adLockUnspecified, -1); + + + // Create SAFEARRAY and wrap it into a VARIANT + // Array is initialized to one element and then redimmed. This is done + // to test SafeArrayRedim, in normal usage it is more efficient to + // intitialize directly to the correct size + SAFEARRAY arr = SAFEARRAY.createSafeArray(1); + arr.putElement(new VARIANT("System.ItemUrl"), 0); + boolean exceptionCaught = false; + try { + arr.putElement(new VARIANT("System.ItemName"), 1); + } catch (COMException ex) { + exceptionCaught = true; + } + assertTrue("Array is initialized to a size of one - it can't hold a second item.", exceptionCaught); + arr.redim(2, 0); + arr.putElement(new VARIANT("System.ItemName"), 1); + + assertThat(arr.getDimensionCount(), is(1)); + + VARIANT columnList = new VARIANT(); + columnList.setValue(Variant.VT_ARRAY | Variant.VT_VARIANT, arr); + + assert !(recordset.getEOF()); + + while (!recordset.getEOF()) { + SAFEARRAY sa = recordset.GetRows(5, VARIANT.VARIANT_MISSING, columnList); + + assertThat(sa.getDimensionCount(), is(2)); + + assertThat(sa.getVarType().intValue(), is(Variant.VT_VARIANT)); + LONGByReference longRef = new LONGByReference(); + + OleAuto.INSTANCE.SafeArrayGetLBound(sa, new UINT(2), longRef); + int lowerBound = longRef.getValue().intValue(); + assertThat(sa.getLBound(0), equalTo(lowerBound)); + + OleAuto.INSTANCE.SafeArrayGetUBound(sa, new UINT(2), longRef); + int upperBound = longRef.getValue().intValue(); + assertThat(sa.getUBound(0), equalTo(upperBound)); + + // 5 rows are expected + assertThat(upperBound - lowerBound + 1, is(5)); + + for (int rowIdx = lowerBound; rowIdx <= upperBound; rowIdx++) { + VARIANT variantItemUrl = (VARIANT) sa.getElement(rowIdx, 0); + VARIANT variantItemName = (VARIANT) sa.getElement(rowIdx, 1); + assertThat(variantItemUrl.stringValue(), is(urls.get(rowIdx))); + assertThat(variantItemName.stringValue(), is(names.get(rowIdx))); + OleAuto.INSTANCE.VariantClear(variantItemUrl); + OleAuto.INSTANCE.VariantClear(variantItemName); + } + + sa.destroy(); + } + + recordset.Close(); + + // Requery and fetch only columns "System.ItemUrl", "System.ItemName" and "System.ItemUrl" + recordset = fact.createObject(Recordset.class); + recordset.Open("SELECT TOP 5 System.ItemPathDisplay, System.ItemName, System.ItemUrl FROM SYSTEMINDEX ORDER BY System.ItemUrl", conn, CursorTypeEnum.adOpenUnspecified, LockTypeEnum.adLockUnspecified, -1); + + assert !(recordset.getEOF()); + + while (!recordset.getEOF()) { + Object[][] data = (Object[][]) OaIdlUtil.toPrimitiveArray(recordset.GetRows(5, VARIANT.VARIANT_MISSING, columnList), true); + + assertThat(data.length, is(5)); + assertThat(data[0].length, is(2)); + + for (int rowIdx = 0; rowIdx < data.length; rowIdx++) { + assertThat((String) data[rowIdx][0], is(urls.get(rowIdx))); + assertThat((String) data[rowIdx][1], is(names.get(rowIdx))); + } + } + + recordset.Close(); + + conn.Close(); + + fact.disposeAll(); + } + + // ------------- Helper classes / interfaces + + /** + *

    + * guid({00000514-0000-0010-8000-00AA006D2EA4})

    + *

    + * source(ConnectionEvents)

    + */ + @ComObject(clsId = "{00000514-0000-0010-8000-00AA006D2EA4}", progId = "{B691E011-1797-432E-907A-4D8C69339129}") + public static interface Connection extends + _Connection, + IConnectionPoint, + IUnknown { + + } + + /** + *

    + * guid({0000051B-0000-0010-8000-00AA006D2EA4})

    + */ + public static enum CursorTypeEnum implements IComEnum { + adOpenUnspecified(-1), + adOpenForwardOnly(0), + adOpenKeyset(1), + adOpenDynamic(2), + adOpenStatic(3),; + + private CursorTypeEnum(long value) { + this.value = value; + } + private long value; + + public long getValue() { + return this.value; + } + } + + /** + *

    + * guid({0000051D-0000-0010-8000-00AA006D2EA4})

    + */ + public static enum LockTypeEnum implements IComEnum { + adLockUnspecified(-1), + adLockReadOnly(1), + adLockPessimistic(2), + adLockOptimistic(3), + adLockBatchOptimistic(4),; + + private LockTypeEnum(long value) { + this.value = value; + } + private long value; + + public long getValue() { + return this.value; + } + } + + /** + *

    + * guid({00000535-0000-0010-8000-00AA006D2EA4})

    + */ + @ComObject(clsId = "{00000535-0000-0010-8000-00AA006D2EA4}", progId = "{00000300-0000-0010-8000-00AA006D2EA4}") + public static interface Recordset extends + _Recordset { + + } + + /** + *

    + * guid({00001550-0000-0010-8000-00AA006D2EA4})

    + */ + @ComInterface(iid = "{00001550-0000-0010-8000-00AA006D2EA4}") + public static interface _Connection { + + /** + *

    + * memberId(5)

    + */ + @ComMethod(name = "Close") + void Close(); + + /** + *

    + * memberId(10)

    + */ + @ComMethod(name = "Open") + void Open(String ConnectionString, + String UserID, + String Password, + int Options); + } + + /** + * + * + *

    + * guid({00000556-0000-0010-8000-00AA006D2EA4})

    + */ + @ComInterface(iid = "{00000556-0000-0010-8000-00AA006D2EA4}") + public static interface _Recordset { + + /** + *

    + * memberId(1006)

    + */ + @ComProperty(name = "EOF") + Boolean getEOF(); + + /** + *

    + * memberId(1016)

    + */ + @ComMethod(name = "GetRows") + SAFEARRAY GetRows(int Rows, + Object Start, + Object Fields); + + /** + *

    + * memberId(1016)

    + */ + @ComMethod(name = "GetRows") + SAFEARRAY GetRows(int Rows); + + /** + *

    + * memberId(1016)

    + */ + @ComMethod(name = "GetRows") + SAFEARRAY GetRows(); + + /** + *

    + * memberId(1014)

    + */ + @ComMethod(name = "Close") + void Close(); + + /** + *

    + * memberId(1022)

    + */ + @ComMethod(name = "Open") + void Open(Object Source, + Object ActiveConnection, + CursorTypeEnum CursorType, + LockTypeEnum LockType, + int Options); + } +} diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/Secur32Test.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/Secur32Test.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/Secur32Test.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/Secur32Test.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,29 +1,31 @@ /* Copyright (c) 2010 Daniel Doubrovkine, All Rights Reserved - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * Lesser General Public License for more details. */ package com.sun.jna.platform.win32; -import junit.framework.TestCase; - import com.sun.jna.Native; import com.sun.jna.platform.win32.Sspi.CredHandle; import com.sun.jna.platform.win32.Sspi.CtxtHandle; import com.sun.jna.platform.win32.Sspi.PSecPkgInfo; import com.sun.jna.platform.win32.Sspi.SecBufferDesc; +import com.sun.jna.platform.win32.Sspi.SecPkgContext_PackageInfo; import com.sun.jna.platform.win32.Sspi.SecPkgInfo; +import com.sun.jna.platform.win32.Sspi.SecPkgInfo.ByReference; import com.sun.jna.platform.win32.Sspi.TimeStamp; import com.sun.jna.platform.win32.WinNT.HANDLEByReference; import com.sun.jna.ptr.IntByReference; +import junit.framework.TestCase; + /** * @author dblock[at]dblock[dot]org */ @@ -32,7 +34,7 @@ public static void main(String[] args) { junit.textui.TestRunner.run(Secur32Test.class); } - + public void testGetUserNameEx() { IntByReference len = new IntByReference(); Secur32.INSTANCE.GetUserNameEx( @@ -44,59 +46,59 @@ String username = Native.toString(buffer); assertTrue(username.length() > 0); } - + public void testAcquireCredentialsHandle() { CredHandle phCredential = new CredHandle(); TimeStamp ptsExpiry = new TimeStamp(); assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.AcquireCredentialsHandle( - null, "Negotiate", Sspi.SECPKG_CRED_OUTBOUND, null, null, null, + null, "Negotiate", Sspi.SECPKG_CRED_OUTBOUND, null, null, null, null, phCredential, ptsExpiry)); assertTrue(phCredential.dwLower != null); assertTrue(phCredential.dwUpper != null); assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeCredentialsHandle( - phCredential)); + phCredential)); } - + public void testAcquireCredentialsHandleInvalidPackage() { CredHandle phCredential = new CredHandle(); TimeStamp ptsExpiry = new TimeStamp(); assertEquals(W32Errors.SEC_E_SECPKG_NOT_FOUND, Secur32.INSTANCE.AcquireCredentialsHandle( - null, "PackageDoesntExist", Sspi.SECPKG_CRED_OUTBOUND, null, null, null, + null, "PackageDoesntExist", Sspi.SECPKG_CRED_OUTBOUND, null, null, null, null, phCredential, ptsExpiry)); } - + public void testInitializeSecurityContext() { CredHandle phCredential = new CredHandle(); TimeStamp ptsExpiry = new TimeStamp(); // acquire a credentials handle assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.AcquireCredentialsHandle( - null, "Negotiate", Sspi.SECPKG_CRED_OUTBOUND, null, null, null, + null, "Negotiate", Sspi.SECPKG_CRED_OUTBOUND, null, null, null, null, phCredential, ptsExpiry)); // initialize security context CtxtHandle phNewContext = new CtxtHandle(); SecBufferDesc pbToken = new SecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE); IntByReference pfContextAttr = new IntByReference(); - int rc = Secur32.INSTANCE.InitializeSecurityContext(phCredential, null, - Advapi32Util.getUserName(), Sspi.ISC_REQ_CONNECTION, 0, - Sspi.SECURITY_NATIVE_DREP, null, 0, phNewContext, pbToken, - pfContextAttr, null); + int rc = Secur32.INSTANCE.InitializeSecurityContext(phCredential, null, + Advapi32Util.getUserName(), Sspi.ISC_REQ_CONNECTION, 0, + Sspi.SECURITY_NATIVE_DREP, null, 0, phNewContext, pbToken, + pfContextAttr, null); assertTrue(rc == W32Errors.SEC_I_CONTINUE_NEEDED || rc == W32Errors.SEC_E_OK); assertTrue(phNewContext.dwLower != null); assertTrue(phNewContext.dwUpper != null); assertTrue(pbToken.pBuffers[0].getBytes().length > 0); - // release + // release assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.DeleteSecurityContext( phNewContext)); assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeCredentialsHandle( phCredential)); } - + public void testAcceptSecurityContext() { // 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, "Negotiate", Sspi.SECPKG_CRED_OUTBOUND, null, null, null, null, phClientCredential, ptsClientExpiry)); // client ----------- security context CtxtHandle phClientContext = new CtxtHandle(); @@ -105,7 +107,7 @@ 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, "Negotiate", Sspi.SECPKG_CRED_INBOUND, null, null, null, null, phServerCredential, ptsServerExpiry)); // server ----------- security context CtxtHandle phServerContext = new CtxtHandle(); @@ -119,37 +121,37 @@ SecBufferDesc pbClientToken = new SecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE); if (clientRc == W32Errors.SEC_I_CONTINUE_NEEDED) { // server token is empty the first time - SecBufferDesc pbServerTokenCopy = pbServerToken == null + SecBufferDesc pbServerTokenCopy = pbServerToken == null ? null : new SecBufferDesc(Sspi.SECBUFFER_TOKEN, pbServerToken.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); + 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 SecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE); SecBufferDesc pbClientTokenByValue = new SecBufferDesc(Sspi.SECBUFFER_TOKEN, pbClientToken.getBytes()); - serverRc = Secur32.INSTANCE.AcceptSecurityContext(phServerCredential, - phServerContext.isNull() ? null : phServerContext, + serverRc = Secur32.INSTANCE.AcceptSecurityContext(phServerCredential, + phServerContext.isNull() ? null : phServerContext, pbClientTokenByValue, - Sspi.ISC_REQ_CONNECTION, - Sspi.SECURITY_NATIVE_DREP, + Sspi.ISC_REQ_CONNECTION, + Sspi.SECURITY_NATIVE_DREP, phServerContext, - pbServerToken, - pfServerContextAttr, - ptsServerExpiry); - assertTrue(serverRc == W32Errors.SEC_I_CONTINUE_NEEDED || serverRc == W32Errors.SEC_E_OK); + 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); // release server context @@ -163,13 +165,13 @@ assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeCredentialsHandle( 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, "Negotiate", Sspi.SECPKG_CRED_OUTBOUND, null, null, null, null, phClientCredential, ptsClientExpiry)); // client ----------- security context CtxtHandle phClientContext = new CtxtHandle(); @@ -178,7 +180,7 @@ 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, "Negotiate", Sspi.SECPKG_CRED_INBOUND, null, null, null, null, phServerCredential, ptsServerExpiry)); // server ----------- security context CtxtHandle phServerContext = new CtxtHandle(); @@ -192,37 +194,37 @@ SecBufferDesc pbClientToken = new SecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE); if (clientRc == W32Errors.SEC_I_CONTINUE_NEEDED) { // server token is empty the first time - SecBufferDesc pbServerTokenCopy = pbServerToken == null + SecBufferDesc pbServerTokenCopy = pbServerToken == null ? null : new SecBufferDesc(Sspi.SECBUFFER_TOKEN, pbServerToken.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); + 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 SecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE); SecBufferDesc pbClientTokenByValue = new SecBufferDesc(Sspi.SECBUFFER_TOKEN, pbClientToken.getBytes()); - serverRc = Secur32.INSTANCE.AcceptSecurityContext(phServerCredential, - phServerContext.isNull() ? null : phServerContext, + serverRc = Secur32.INSTANCE.AcceptSecurityContext(phServerCredential, + phServerContext.isNull() ? null : phServerContext, pbClientTokenByValue, - Sspi.ISC_REQ_CONNECTION, - Sspi.SECURITY_NATIVE_DREP, + Sspi.ISC_REQ_CONNECTION, + Sspi.SECURITY_NATIVE_DREP, phServerContext, - pbServerToken, - pfServerContextAttr, - ptsServerExpiry); - assertTrue(serverRc == W32Errors.SEC_I_CONTINUE_NEEDED || serverRc == W32Errors.SEC_E_OK); + 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 @@ -241,28 +243,29 @@ assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeCredentialsHandle( phClientCredential)); } - + public void testEnumerateSecurityPackages() { IntByReference pcPackages = new IntByReference(); PSecPkgInfo.ByReference pPackageInfo = new PSecPkgInfo.ByReference(); assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.EnumerateSecurityPackages( pcPackages, pPackageInfo)); SecPkgInfo.ByReference[] packagesInfo = pPackageInfo.toArray( - pcPackages.getValue()); + pcPackages.getValue()); for(SecPkgInfo.ByReference packageInfo : packagesInfo) { assertTrue(packageInfo.Name.length() > 0); assertTrue(packageInfo.Comment.length() >= 0); } assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeContextBuffer( - pPackageInfo.getPointer())); + pPackageInfo.pPkgInfo.getPointer())); + } - + public void testQuerySecurityContextToken() { // 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, "Negotiate", Sspi.SECPKG_CRED_OUTBOUND, null, null, null, null, phClientCredential, ptsClientExpiry)); // client ----------- security context CtxtHandle phClientContext = new CtxtHandle(); @@ -271,7 +274,7 @@ 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, "Negotiate", Sspi.SECPKG_CRED_INBOUND, null, null, null, null, phServerCredential, ptsServerExpiry)); // server ----------- security context CtxtHandle phServerContext = new CtxtHandle(); @@ -286,40 +289,40 @@ if (clientRc == W32Errors.SEC_I_CONTINUE_NEEDED) { // server token is empty the first time clientRc = Secur32.INSTANCE.InitializeSecurityContext( - phClientCredential, - phClientContext.isNull() ? null : phClientContext, - Advapi32Util.getUserName(), - Sspi.ISC_REQ_CONNECTION, - 0, - Sspi.SECURITY_NATIVE_DREP, - pbServerToken, - 0, - phClientContext, - pbClientToken, - pfClientContextAttr, - null); - assertTrue(clientRc == W32Errors.SEC_I_CONTINUE_NEEDED || clientRc == W32Errors.SEC_E_OK); - } + phClientCredential, + phClientContext.isNull() ? null : phClientContext, + Advapi32Util.getUserName(), + Sspi.ISC_REQ_CONNECTION, + 0, + Sspi.SECURITY_NATIVE_DREP, + pbServerToken, + 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) { - serverRc = Secur32.INSTANCE.AcceptSecurityContext(phServerCredential, - phServerContext.isNull() ? null : phServerContext, - pbClientToken, - Sspi.ISC_REQ_CONNECTION, - Sspi.SECURITY_NATIVE_DREP, + serverRc = Secur32.INSTANCE.AcceptSecurityContext(phServerCredential, + phServerContext.isNull() ? null : phServerContext, + pbClientToken, + Sspi.ISC_REQ_CONNECTION, + Sspi.SECURITY_NATIVE_DREP, phServerContext, - pbServerToken, - pfServerContextAttr, + 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); + } + } while(serverRc != W32Errors.SEC_E_OK || clientRc != W32Errors.SEC_E_OK); // query security context token HANDLEByReference phContextToken = new HANDLEByReference(); assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.QuerySecurityContextToken( phServerContext, phContextToken)); // release security context token - assertTrue(Kernel32.INSTANCE.CloseHandle(phContextToken.getValue())); + Kernel32Util.closeHandleRef(phContextToken); // release server context assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.DeleteSecurityContext( phServerContext)); @@ -329,9 +332,9 @@ assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.DeleteSecurityContext( phClientContext)); assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeCredentialsHandle( - phClientCredential)); + phClientCredential)); } - + public void testCreateEmptyToken() { SecBufferDesc token = new SecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE); assertEquals(1, token.pBuffers.length); @@ -340,4 +343,68 @@ assertEquals(Sspi.MAX_TOKEN_SIZE, token.pBuffers[0].cbBuffer); assertEquals(token.getBytes().length, token.pBuffers[0].getBytes().length); } + + public void testQueryContextAttributes() { + // 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(); + SecBufferDesc pbServerToken = new SecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE); + IntByReference pfServerContextAttr = new IntByReference(); + int clientRc = W32Errors.SEC_I_CONTINUE_NEEDED; + int serverRc = W32Errors.SEC_I_CONTINUE_NEEDED; + do { + // client token returned is always new + SecBufferDesc pbClientToken = new SecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE); + // client ----------- initialize security context, produce a client + // token + if (clientRc == W32Errors.SEC_I_CONTINUE_NEEDED) { + // server token is empty the first time + clientRc = Secur32.INSTANCE.InitializeSecurityContext(phClientCredential, + phClientContext.isNull() ? null : phClientContext, Advapi32Util.getUserName(), + Sspi.ISC_REQ_CONNECTION, 0, Sspi.SECURITY_NATIVE_DREP, pbServerToken, 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) { + serverRc = Secur32.INSTANCE.AcceptSecurityContext(phServerCredential, phServerContext.isNull() ? null + : phServerContext, pbClientToken, 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); + // query context attributes + SecPkgContext_PackageInfo packageinfo = new SecPkgContext_PackageInfo(); + assertEquals(W32Errors.SEC_E_OK, + Secur32.INSTANCE.QueryContextAttributes(phServerContext, Sspi.SECPKG_ATTR_PACKAGE_INFO, packageinfo)); + ByReference info = packageinfo.PackageInfo; + + assertNotNull(info.Name); + assertNotNull(info.Comment); + + assertTrue(!info.Name.isEmpty()); + assertTrue(!info.Comment.isEmpty()); + + assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeContextBuffer(info.getPointer())); + + // 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 -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/Shell32Test.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/Shell32Test.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/Shell32Test.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/Shell32Test.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,30 +1,34 @@ /* Copyright (c) 2010, 2013 Daniel Doubrovkine, Markus Karg, All Rights Reserved - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * Lesser General Public License for more details. */ package com.sun.jna.platform.win32; -import junit.framework.TestCase; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; import com.sun.jna.Native; +import com.sun.jna.WString; import com.sun.jna.platform.win32.Guid.GUID; import com.sun.jna.platform.win32.ShellAPI.APPBARDATA; +import com.sun.jna.platform.win32.ShellAPI.SHELLEXECUTEINFO; import com.sun.jna.platform.win32.WinDef.DWORD; -import com.sun.jna.platform.win32.WinDef.LPVOID; -import com.sun.jna.platform.win32.WinDef.RECT; import com.sun.jna.platform.win32.WinDef.UINT_PTR; import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.platform.win32.WinNT.HRESULT; import com.sun.jna.ptr.PointerByReference; +import junit.framework.TestCase; + /** * @author dblock[at]dblock[dot]org @@ -32,7 +36,8 @@ */ public class Shell32Test extends TestCase { - private static final int RESIZE_HEIGHT = 500; + // avoid disrupting the screen _too_ much + private static final int RESIZE_DELTA = 10; private static final int WM_USER = 0x0400; public static void main(String[] args) { @@ -41,27 +46,26 @@ public void testSHGetFolderPath() { char[] pszPath = new char[WinDef.MAX_PATH]; - assertEquals(W32Errors.S_OK, Shell32.INSTANCE.SHGetFolderPath(null, - ShlObj.CSIDL_PROGRAM_FILES, null, ShlObj.SHGFP_TYPE_CURRENT, - pszPath)); - assertTrue(Native.toString(pszPath).length() > 0); + assertEquals("Failed to retrieve path", W32Errors.S_OK, + Shell32.INSTANCE.SHGetFolderPath(null, ShlObj.CSIDL_PROGRAM_FILES, null, ShlObj.SHGFP_TYPE_CURRENT, pszPath)); + assertTrue("Empty path", Native.toString(pszPath).length() > 0); } public void testSHGetDesktopFolder() { PointerByReference ppshf = new PointerByReference(); WinNT.HRESULT hr = Shell32.INSTANCE.SHGetDesktopFolder(ppshf); - assertTrue(W32Errors.SUCCEEDED(hr.intValue())); - assertTrue(ppshf.getValue() != null); + assertTrue("Failed to get folder: " + hr.intValue(), W32Errors.SUCCEEDED(hr.intValue())); + assertTrue("No folder value", ppshf.getValue() != null); // should release the interface, but we need Com4JNA to do that. } public final void testSHGetSpecialFolderPath() { final char[] pszPath = new char[WinDef.MAX_PATH]; - assertTrue(Shell32.INSTANCE.SHGetSpecialFolderPath(null, pszPath, ShlObj.CSIDL_APPDATA, false)); - assertFalse(Native.toString(pszPath).isEmpty()); + assertTrue("SHGetSpecialFolderPath", Shell32.INSTANCE.SHGetSpecialFolderPath(null, pszPath, ShlObj.CSIDL_APPDATA, false)); + assertFalse("No path", Native.toString(pszPath).isEmpty()); } - + private void newAppBar() { APPBARDATA data = new APPBARDATA.ByReference(); data.cbSize.setValue(data.size()); @@ -94,7 +98,7 @@ APPBARDATA data = new APPBARDATA.ByReference(); data.uEdge.setValue(ShellAPI.ABE_BOTTOM); - data.rc.top = User32.INSTANCE.GetSystemMetrics(User32.SM_CYFULLSCREEN) - RESIZE_HEIGHT; + data.rc.top = User32.INSTANCE.GetSystemMetrics(User32.SM_CYFULLSCREEN) - RESIZE_DELTA; data.rc.left = 0; data.rc.bottom = User32.INSTANCE.GetSystemMetrics(User32.SM_CYFULLSCREEN); data.rc.right = User32.INSTANCE.GetSystemMetrics(User32.SM_CXFULLSCREEN); @@ -110,14 +114,14 @@ } public void testResizeDesktopFromTop() throws InterruptedException { - + newAppBar(); APPBARDATA data = new APPBARDATA.ByReference(); data.uEdge.setValue(ShellAPI.ABE_TOP); data.rc.top = 0; data.rc.left = 0; - data.rc.bottom = RESIZE_HEIGHT; + data.rc.bottom = User32.INSTANCE.GetSystemMetrics(User32.SM_CXFULLSCREEN) - RESIZE_DELTA; data.rc.right = User32.INSTANCE.GetSystemMetrics(User32.SM_CXFULLSCREEN); queryPos(data); @@ -131,8 +135,7 @@ } - public void testSHGetKnownFolderPath() - { + public void testSHGetKnownFolderPath() { int flags = ShlObj.KNOWN_FOLDER_FLAG.NONE.getFlag(); PointerByReference outPath = new PointerByReference(); HANDLE token = null; @@ -143,4 +146,107 @@ assertTrue(W32Errors.SUCCEEDED(hr.intValue())); } + + public void testSHEmptyRecycleBin() { + File file = new File(System.getProperty("java.io.tmpdir"), System.nanoTime() + ".txt"); + try { + // Create a file and immediately send it to the recycle bin. + try { + fillTempFile(file); + W32FileUtils.getInstance().moveToTrash(new File[] { file }); + } catch (IOException e) { + throw new RuntimeException(e); + } + + int result = Shell32.INSTANCE.SHEmptyRecycleBin(null, null, + Shell32.SHERB_NOCONFIRMATION | Shell32.SHERB_NOPROGRESSUI | Shell32.SHERB_NOSOUND); + // for reasons I can not find documented on MSDN, + // the function returns the following: + // 0 when the recycle bin has items in it + // -2147418113 when the recycle bin has no items in it + assertEquals("Result should have been ERROR_SUCCESS when emptying Recycle Bin - there should have been a file in it.", + W32Errors.ERROR_SUCCESS, result); + } finally { + // if the file wasn't sent to the recycle bin, delete it. + if (file.exists()) { + file.delete(); + } + } + } + + public void testShellExecuteEx() { + File file = new File(System.getProperty("java.io.tmpdir"), System.nanoTime() + ".txt"); + try { + try { + fillTempFile(file); + } catch (IOException e) { + throw new RuntimeException(e); + } + + SHELLEXECUTEINFO lpExecInfo = new SHELLEXECUTEINFO(); + // to avoid opening something and having hProcess come up null + // (meaning we opened something but can't close it) + // we will do a negative test with a bogus action. + lpExecInfo.lpVerb = "0p3n"; + lpExecInfo.nShow = User32.SW_SHOWDEFAULT; + lpExecInfo.fMask = Shell32.SEE_MASK_NOCLOSEPROCESS | Shell32.SEE_MASK_FLAG_NO_UI; + lpExecInfo.lpFile = file.getAbsolutePath(); + + assertFalse("ShellExecuteEx should have returned false - action verb was bogus.", + Shell32.INSTANCE.ShellExecuteEx(lpExecInfo)); + assertEquals("GetLastError() should have been set to ERROR_NO_ASSOCIATION because of bogus action", + W32Errors.ERROR_NO_ASSOCIATION, Native.getLastError()); + } finally { + if (file.exists()) { + file.delete(); + } + } + + } + + /** + * Creates (if needed) and fills the specified file with some content (10 lines of the same text) + * + * @param file + * The file to fill with content + * @throws IOException + * If writing the content fails + */ + private void fillTempFile(File file) throws IOException { + file.createNewFile(); + FileWriter fileWriter = new FileWriter(file); + try { + for (int i = 0; i < 10; i++) { + fileWriter.write("Sample line of text"); + fileWriter.write(System.getProperty("line.separator")); + } + } finally { + fileWriter.close(); + } + } + + public void testExtractIconEx() { + String winDir = Kernel32Util.getEnvironmentVariable("WINDIR"); + assertNotNull("No WINDIR value returned", winDir); + assertTrue("Specified WINDIR does not exist: " + winDir, new File(winDir).exists()); + + int iconCount = Shell32.INSTANCE.ExtractIconEx(new File(winDir, "explorer.exe").getAbsolutePath(), -1, null, null, 1); + assertTrue("Should be at least two icons in explorer.exe", iconCount > 1); + } + + public void testCurrentProcessExplicitAppUserModelID() { + String appUserModelID = "com.sun.jna.platform.win32.Shell32Test"; + + HRESULT r1 = Shell32.INSTANCE.SetCurrentProcessExplicitAppUserModelID(new WString(appUserModelID)); + assertEquals(WinError.S_OK, r1); + + PointerByReference ppszAppID = new PointerByReference(); + HRESULT r2 = Shell32.INSTANCE.GetCurrentProcessExplicitAppUserModelID(ppszAppID); + assertEquals(WinError.S_OK, r2); + + assertEquals(appUserModelID, ppszAppID.getValue().getWideString(0)); + + Ole32.INSTANCE.CoTaskMemFree(ppszAppID.getValue()); + } + } diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/ShlwapiTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/ShlwapiTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/ShlwapiTest.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/ShlwapiTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,24 @@ +package com.sun.jna.platform.win32; + +import junit.framework.TestCase; + +public class ShlwapiTest extends TestCase { + + public static void main(String[] args) { + junit.textui.TestRunner.run(ShlwapiTest.class); + } + + public void testPathIsUNC() { + assertEquals(true, Shlwapi.INSTANCE.PathIsUNC("\\\\path1\\path2")); + assertEquals(true, Shlwapi.INSTANCE.PathIsUNC("\\\\path1")); + assertEquals(false, Shlwapi.INSTANCE.PathIsUNC("acme\\\\path4\\\\path5")); + assertEquals(true, Shlwapi.INSTANCE.PathIsUNC("\\\\")); + assertEquals(true, Shlwapi.INSTANCE.PathIsUNC("\\\\?\\UNC\\path1\\path2")); + assertEquals(true, Shlwapi.INSTANCE.PathIsUNC("\\\\?\\UNC\\path1")); + assertEquals(true, Shlwapi.INSTANCE.PathIsUNC("\\\\?\\UNC\\")); + assertEquals(false, Shlwapi.INSTANCE.PathIsUNC("\\path1")); + assertEquals(false, Shlwapi.INSTANCE.PathIsUNC("path1")); + assertEquals(false, Shlwapi.INSTANCE.PathIsUNC("c:\\path1")); + assertEquals(false, Shlwapi.INSTANCE.PathIsUNC("\\\\?\\c:\\path1")); + } +} diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/User32Test.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/User32Test.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/User32Test.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/User32Test.java 2017-03-14 19:31:03.000000000 +0000 @@ -25,9 +25,11 @@ import org.junit.Test; import org.junit.runner.JUnitCore; +import com.sun.jna.Native; import com.sun.jna.Pointer; import com.sun.jna.platform.DesktopWindow; import com.sun.jna.platform.WindowUtils; +import com.sun.jna.platform.win32.BaseTSD.ULONG_PTR; import com.sun.jna.platform.win32.WinDef.BOOL; import com.sun.jna.platform.win32.WinDef.DWORD; import com.sun.jna.platform.win32.WinDef.DWORDByReference; @@ -35,9 +37,11 @@ import com.sun.jna.platform.win32.WinDef.HICON; import com.sun.jna.platform.win32.WinDef.HWND; import com.sun.jna.platform.win32.WinDef.LPARAM; +import com.sun.jna.platform.win32.WinDef.LRESULT; import com.sun.jna.platform.win32.WinDef.POINT; import com.sun.jna.platform.win32.WinDef.RECT; import com.sun.jna.platform.win32.WinDef.UINT; +import com.sun.jna.platform.win32.WinDef.WPARAM; import com.sun.jna.platform.win32.WinGDI.ICONINFO; import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.platform.win32.WinUser.HMONITOR; @@ -52,33 +56,33 @@ public class User32Test extends AbstractWin32TestSupport { public static void main(String[] args) { - JUnitCore.runClasses(User32Test.class); + JUnitCore.runClasses(User32Test.class); } - /** - * Iterates over all currently available Desktop windows and searches for - * the window with the associated process whose full PE file path ends with - * the specified string (case insensitive). - * - * @param filePathEnd - * The requested end of the process' full file path. - * @return Either the found window or {@code null} if nothing was found. - */ - private static DesktopWindow getWindowByProcessPath(final String filePathEnd) { - final List allWindows = WindowUtils.getAllWindows(false); - for (final DesktopWindow wnd : allWindows) { - if (wnd.getFilePath().toLowerCase() - .endsWith(filePathEnd.toLowerCase())) { - return wnd; - } - } + /** + * Iterates over all currently available Desktop windows and searches for + * the window with the associated process whose full PE file path ends with + * the specified string (case insensitive). + * + * @param filePathEnd + * The requested end of the process' full file path. + * @return Either the found window or {@code null} if nothing was found. + */ + private static DesktopWindow getWindowByProcessPath(final String filePathEnd) { + final List allWindows = WindowUtils.getAllWindows(false); + for (final DesktopWindow wnd : allWindows) { + if (wnd.getFilePath().toLowerCase() + .endsWith(filePathEnd.toLowerCase())) { + return wnd; + } + } - return null; + return null; } - @Test + @Test public void testNoDuplicateMethodsNames() { - // see https://github.com/twall/jna/issues/482 + // see https://github.com/twall/jna/issues/482 Collection dupSet = AbstractWin32TestSupport.detectDuplicateMethods(User32.class); if (dupSet.size() > 0) { for (String name : new String[] { @@ -201,7 +205,7 @@ @Test public final void testGetMonitorInfo() { - HMONITOR hMon = User32.INSTANCE.MonitorFromPoint(new POINT(0, 0), WinUser.MONITOR_DEFAULTTOPRIMARY); + HMONITOR hMon = User32.INSTANCE.MonitorFromWindow(User32.INSTANCE.GetDesktopWindow(), WinUser.MONITOR_DEFAULTTOPRIMARY); assertTrue(User32.INSTANCE.GetMonitorInfo(hMon, new MONITORINFO()).booleanValue()); @@ -223,80 +227,186 @@ @Test public final void testAdjustWindowRect() { - RECT lpRect = new RECT(); - lpRect.left = 100; - lpRect.top = 200; - lpRect.bottom = 300; - lpRect.right = 500; - - assertTrue(User32.INSTANCE.AdjustWindowRect(lpRect, new DWORD(WinUser.WS_THICKFRAME), new BOOL(1)).booleanValue()); - - assertTrue(lpRect.left < 100); - assertTrue(lpRect.top < 200); - assertTrue(lpRect.bottom > 300); - assertTrue(lpRect.right > 500); + RECT lpRect = new RECT(); + lpRect.left = 100; + lpRect.top = 200; + lpRect.bottom = 300; + lpRect.right = 500; + + assertTrue(User32.INSTANCE.AdjustWindowRect(lpRect, new DWORD(WinUser.WS_THICKFRAME), new BOOL(1)).booleanValue()); + + assertTrue(lpRect.left < 100); + assertTrue(lpRect.top < 200); + assertTrue(lpRect.bottom > 300); + assertTrue(lpRect.right > 500); } @Ignore("Locks the workstation") @Test public final void testLockWorkStation() { - assertTrue(User32.INSTANCE.LockWorkStation().booleanValue()); + assertTrue(User32.INSTANCE.LockWorkStation().booleanValue()); } - @Ignore("Shutsdown the workstation") + @Ignore("Shuts down the workstation") @Test public final void testExitWindows() { - assertTrue(User32.INSTANCE.ExitWindowsEx(new UINT(WinUser.EWX_LOGOFF), new DWORD(0x00030000)).booleanValue()); //This only tries to log off. + assertTrue(User32.INSTANCE.ExitWindowsEx(new UINT(WinUser.EWX_LOGOFF), new DWORD(0x00030000)).booleanValue()); //This only tries to log off. + } + + @Test + public void testGetIconInfo() throws Exception { + final ICONINFO iconInfo = new ICONINFO(); + final HANDLE hImage = User32.INSTANCE.LoadImage(null, new File( + getClass().getResource("/res/test_icon.ico").toURI()) + .getAbsolutePath(), WinUser.IMAGE_ICON, 0, 0, + WinUser.LR_LOADFROMFILE); + + try { + // obtain test icon from classpath + if (!User32.INSTANCE.GetIconInfo(new HICON(hImage), iconInfo)) + throw new Exception( + "Invocation of User32.GetIconInfo() failed: " + + Kernel32Util.getLastErrorMessage()); + iconInfo.read(); + } finally { + if (iconInfo.hbmColor != null + && iconInfo.hbmColor.getPointer() != Pointer.NULL) + GDI32.INSTANCE.DeleteObject(iconInfo.hbmColor); + if (iconInfo.hbmMask != null + && iconInfo.hbmMask.getPointer() != Pointer.NULL) + GDI32.INSTANCE.DeleteObject(iconInfo.hbmMask); + } } @Test - public void testGetIconInfo() throws Exception { - final ICONINFO iconInfo = new ICONINFO(); - final HANDLE hImage = User32.INSTANCE.LoadImage(null, new File( - getClass().getResource("/res/test_icon.ico").toURI()) - .getAbsolutePath(), WinUser.IMAGE_ICON, 0, 0, - WinUser.LR_LOADFROMFILE); - - try { - // obtain test icon from classpath - if (!User32.INSTANCE.GetIconInfo(new HICON(hImage), iconInfo)) - throw new Exception( - "Invocation of User32.GetIconInfo() failed: " - + Kernel32Util.getLastErrorMessage()); - iconInfo.read(); - } finally { - if (iconInfo.hbmColor != null - && iconInfo.hbmColor.getPointer() != Pointer.NULL) - GDI32.INSTANCE.DeleteObject(iconInfo.hbmColor); - if (iconInfo.hbmMask != null - && iconInfo.hbmMask.getPointer() != Pointer.NULL) - GDI32.INSTANCE.DeleteObject(iconInfo.hbmMask); - } - } - - @Test - public void testSendMessageTimeout() { - DesktopWindow explorerProc = getWindowByProcessPath("explorer.exe"); - - assertNotNull(explorerProc); - - final DWORDByReference hIconNumber = new DWORDByReference(); - long result = User32.INSTANCE.SendMessageTimeout( - explorerProc.getHWND(), WinUser.WM_GETICON, WinUser.ICON_BIG, - 0, WinUser.SMTO_ABORTIFHUNG, 500, hIconNumber); - - assertNotEquals(0, result); - } - - @Test - public void testGetClassLongPtr() { - DesktopWindow explorerProc = getWindowByProcessPath("explorer.exe"); + public void testSendMessageTimeout() { + DesktopWindow explorerProc = getWindowByProcessPath("explorer.exe"); - assertNotNull(explorerProc); + assertNotNull(explorerProc); - long result = User32.INSTANCE.GetClassLongPtr(explorerProc.getHWND(), - WinUser.GCLP_HMODULE); + final DWORDByReference hIconNumber = new DWORDByReference(); + LRESULT result = User32.INSTANCE + .SendMessageTimeout(explorerProc.getHWND(), + WinUser.WM_GETICON, + new WPARAM(WinUser.ICON_BIG), + new LPARAM(0), + WinUser.SMTO_ABORTIFHUNG, 500, hIconNumber); - assertNotEquals(0, result); - } + assertNotEquals(0, result); + } + + @Test + public void testGetClassLongPtr() { + if (System.getProperty("os.arch", "unknown").equalsIgnoreCase("amd64")) { + DesktopWindow explorerProc = getWindowByProcessPath("explorer.exe"); + + assertNotNull("Could not find explorer.exe process", + explorerProc); + + ULONG_PTR result = User32.INSTANCE + .GetClassLongPtr(explorerProc.getHWND(), + WinUser.GCLP_HMODULE); + + assertNotEquals(0, result.intValue()); + } else { + System.err.println("GetClassLongPtr only supported on x64"); + } + } + + @Test + public void testGetDesktopWindow() { + HWND desktopWindow = User32.INSTANCE.GetDesktopWindow(); + assertNotNull("Failed to get desktop window HWND", desktopWindow); + } + + @Test + public void testPrintWindow() { + boolean pwResult = User32.INSTANCE.PrintWindow(null, null, 0); + assertFalse("PrintWindow result should be false", pwResult); + assertEquals("GetLastError should be ERROR_INVALID_WINDOW_HANDLE.", WinError.ERROR_INVALID_WINDOW_HANDLE, Native.getLastError()); + } + + @Test + public void testIsWindowEnabled() { + boolean iweResult = User32.INSTANCE.IsWindowEnabled(null); + assertFalse("IsWindowEnabled result should be false", iweResult); + assertEquals("GetLastError should be ERROR_INVALID_WINDOW_HANDLE.", WinError.ERROR_INVALID_WINDOW_HANDLE, Native.getLastError()); + } + + @Test + public void testIsWindow() { + boolean iwResult = User32.INSTANCE.IsWindow(null); + assertFalse("IsWindow result should be false", iwResult); + assertEquals("GetLastError should be ERROR_SUCCESS.", WinError.ERROR_SUCCESS, Native.getLastError()); + } + + @Test + public void testFindWindowEx() { + HWND result = User32.INSTANCE.FindWindowEx(null, null, null, null); + assertNotNull("FindWindowEx result should not be null", result); + assertEquals("GetLastError should be ERROR_SUCCESS.", WinError.ERROR_SUCCESS, Native.getLastError()); + } + + @Test + public void testGetAncestor() { + HWND desktopWindow = User32.INSTANCE.GetDesktopWindow(); + assertNotNull("Failed to get desktop window HWND", desktopWindow); + + HWND result = User32.INSTANCE.GetAncestor(desktopWindow, WinUser.GA_PARENT); + assertNull("GetAncestor result should be null", result); + assertEquals("GetLastError should be ERROR_SUCCESS.", WinError.ERROR_SUCCESS, Native.getLastError()); + } + + @Test + public void testGetCursorPos() { + POINT cursorPos = new POINT(); + boolean result = User32.INSTANCE.GetCursorPos(cursorPos); + assertTrue("GetCursorPos should return true", result); + assertTrue("X coordinate in POINT should be >= 0", cursorPos.x >= 0); + assertTrue("Y coordinate in POINT should be >= 0", cursorPos.y >= 0); + } + + @Test + public void testSetCursorPos() { + POINT cursorPos = new POINT(); + boolean result = User32.INSTANCE.GetCursorPos(cursorPos); + assertTrue("GetCursorPos should return true", result); + assertTrue("X coordinate in POINT should be >= 0", cursorPos.x >= 0); + + boolean scpResult = User32.INSTANCE.SetCursorPos(cursorPos.x - 20, cursorPos.y); + assertTrue("SetCursorPos should return true", scpResult); + + POINT cursorPos2 = new POINT(); + boolean result2 = User32.INSTANCE.GetCursorPos(cursorPos2); + assertTrue("GetCursorPos should return true", result2); + assertTrue("X coordinate in POINT should be original cursor position - 20", cursorPos2.x == cursorPos.x - 20); + } + + @Test + public void testSetWinEventHook() { + HANDLE result = User32.INSTANCE.SetWinEventHook(0, 0, null, null, 0, 0, 0); + assertNull("SetWinEventHook result should be null", result); + assertEquals("GetLastError should be ERROR_INVALID_FILTER_PROC.", WinError.ERROR_INVALID_FILTER_PROC, Native.getLastError()); + } + + @Test + public void testUnhookWinEvent() { + boolean iwResult = User32.INSTANCE.UnhookWinEvent(null); + assertFalse("UnhookWinEvent result should be false", iwResult); + assertEquals("GetLastError should be ERROR_INVALID_HANDLE.", WinError.ERROR_INVALID_HANDLE, Native.getLastError()); + } + + @Test + public void testCopyIcon() { + HICON result = User32.INSTANCE.CopyIcon(null); + assertNull("CopyIcon result should be false", result); + assertEquals("GetLastError should be ERROR_INVALID_CURSOR_HANDLE.", WinError.ERROR_INVALID_CURSOR_HANDLE, Native.getLastError()); + } + + @Test + public void testGetClassLong() { + int result = User32.INSTANCE.GetClassLong(null, 0); + assertEquals("GetClassLong result should be 0", 0, result); + assertEquals("GetLastError should be ERROR_INVALID_WINDOW_HANDLE.", WinError.ERROR_INVALID_WINDOW_HANDLE, Native.getLastError()); + } } diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/VariantTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/VariantTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/VariantTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/VariantTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -2,16 +2,29 @@ import junit.framework.TestCase; -import com.sun.jna.Native; import com.sun.jna.platform.win32.OaIdl.DATE; +import com.sun.jna.platform.win32.OaIdl.SAFEARRAY; +import com.sun.jna.platform.win32.OaIdl.VARIANT_BOOL; import com.sun.jna.platform.win32.Variant.VARIANT; +import com.sun.jna.platform.win32.WTypes.BSTR; +import com.sun.jna.platform.win32.WTypes.VARTYPE; import com.sun.jna.platform.win32.WinBase.SYSTEMTIME; +import com.sun.jna.platform.win32.WinDef.BOOL; +import com.sun.jna.platform.win32.WinDef.BYTE; +import com.sun.jna.platform.win32.WinDef.CHAR; +import com.sun.jna.platform.win32.WinDef.LONG; +import com.sun.jna.platform.win32.WinDef.LONGLONG; import com.sun.jna.platform.win32.WinDef.SHORT; +import com.sun.jna.platform.win32.WinDef.USHORT; import com.sun.jna.platform.win32.WinNT.HRESULT; import com.sun.jna.ptr.DoubleByReference; - import java.util.Date; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + public class VariantTest extends TestCase { public static void main(String[] args) { @@ -19,11 +32,12 @@ } public VariantTest() { + super(); } public void testVariantClear() { VARIANT variant = new VARIANT(new SHORT(33333)); - HRESULT hr = OleAuto.INSTANCE.VariantClear(variant.getPointer()); + HRESULT hr = OleAuto.INSTANCE.VariantClear(variant); assertTrue("hr: " + hr.intValue(), hr.intValue() == 0); } @@ -68,17 +82,187 @@ pvRecord2 = (VARIANT._VARIANT.__VARIANT.BRECORD)variant.getValue(); } + + 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 + + // From Date to DATE + assertThat(new DATE(new Date(1899 - 1900, 12 - 1, 27, 0, 0, 0)).date, equalTo(-3.00d)); + assertThat(new DATE(new Date(1899 - 1900, 12 - 1, 28, 12, 0, 0)).date, equalTo(-2.50d)); + assertThat(new DATE(new Date(1899 - 1900, 12 - 1, 28, 0, 0, 0)).date, equalTo(-2.00d)); + assertThat(new DATE(new Date(1899 - 1900, 12 - 1, 29, 0, 0, 0)).date, equalTo(-1.00d)); + assertThat(new DATE(new Date(1899 - 1900, 12 - 1, 30, 0, 0, 0)).date, equalTo(0.00d)); + assertThat(new DATE(new Date(1899 - 1900, 12 - 1, 30, 6, 0, 0)).date, equalTo(0.25d)); + assertThat(new DATE(new Date(1899 - 1900, 12 - 1, 30, 12, 0, 0)).date, equalTo(0.50d)); + assertThat(new DATE(new Date(1899 - 1900, 12 - 1, 30, 18, 0, 0)).date, equalTo(0.75d)); + assertThat(new DATE(new Date(1899 - 1900, 12 - 1, 31, 0, 0, 0)).date, equalTo(1.0d)); + assertThat(new DATE(new Date(1900 - 1900, 1 - 1, 1, 0, 0, 0)).date, equalTo(2.00d)); + assertThat(new DATE(new Date(1900 - 1900, 1 - 1, 1, 12, 0, 0)).date, equalTo(2.50d)); + assertThat(new DATE(new Date(1900 - 1900, 1 - 1, 2, 0, 0, 0)).date, equalTo(3.00d)); + assertThat(new DATE(new Date(1900 - 1900, 1 - 1, 4, 0, 0, 0)).date, equalTo(5.00d)); + assertThat(new DATE(new Date(1900 - 1900, 1 - 1, 4, 6, 0, 0)).date, equalTo(5.25d)); + assertThat(new DATE(new Date(1900 - 1900, 1 - 1, 4, 12, 0, 0)).date, equalTo(5.50d)); + assertThat(new DATE(new Date(1900 - 1900, 1 - 1, 4, 21, 0, 0)).date, equalTo(5.875d)); + + // From DATE to Date + assertThat(new DATE(-3.00d).getAsJavaDate(), equalTo(new Date(1899 - 1900, 12 - 1, 27, 0, 0, 0))); + assertThat(new DATE(-2.50d).getAsJavaDate(), equalTo(new Date(1899 - 1900, 12 - 1, 28, 12, 0, 0))); + assertThat(new DATE(-2.00d).getAsJavaDate(), equalTo(new Date(1899 - 1900, 12 - 1, 28, 0, 0, 0))); + assertThat(new DATE(-1.00d).getAsJavaDate(), equalTo(new Date(1899 - 1900, 12 - 1, 29, 0, 0, 0))); + assertThat(new DATE(-0.75d).getAsJavaDate(), equalTo(new Date(1899 - 1900, 12 - 1, 30, 18, 0, 0))); + assertThat(new DATE(-0.50d).getAsJavaDate(), equalTo(new Date(1899 - 1900, 12 - 1, 30, 12, 0, 0))); + assertThat(new DATE(-0.25d).getAsJavaDate(), equalTo(new Date(1899 - 1900, 12 - 1, 30, 6, 0, 0))); + assertThat(new DATE(0.00d).getAsJavaDate(), equalTo(new Date(1899 - 1900, 12 - 1, 30, 0, 0, 0))); + assertThat(new DATE(0.25d).getAsJavaDate(), equalTo(new Date(1899 - 1900, 12 - 1, 30, 6, 0, 0))); + assertThat(new DATE(0.50d).getAsJavaDate(), equalTo(new Date(1899 - 1900, 12 - 1, 30, 12, 0, 0))); + assertThat(new DATE(0.75d).getAsJavaDate(), equalTo(new Date(1899 - 1900, 12 - 1, 30, 18, 0, 0))); + assertThat(new DATE(1.0d).getAsJavaDate(), equalTo(new Date(1899 - 1900, 12 - 1, 31, 0, 0, 0))); + assertThat(new DATE(2.00d).getAsJavaDate(), equalTo(new Date(1900 - 1900, 1 - 1, 1, 0, 0, 0))); + assertThat(new DATE(2.50d).getAsJavaDate(), equalTo(new Date(1900 - 1900, 1 - 1, 1, 12, 0, 0))); + assertThat(new DATE(3.00d).getAsJavaDate(), equalTo(new Date(1900 - 1900, 1 - 1, 2, 0, 0, 0))); + assertThat(new DATE(5.00d).getAsJavaDate(), equalTo(new Date(1900 - 1900, 1 - 1, 4, 0, 0, 0))); + assertThat(new DATE(5.25d).getAsJavaDate(), equalTo(new Date(1900 - 1900, 1 - 1, 4, 6, 0, 0))); + assertThat(new DATE(5.50d).getAsJavaDate(), equalTo(new Date(1900 - 1900, 1 - 1, 4, 12, 0, 0))); + assertThat(new DATE(5.875d).getAsJavaDate(), equalTo(new Date(1900 - 1900, 1 - 1, 4, 21, 0, 0))); + + // Test roundtripping with sub hour resolution + // This test allows for a rounding error of 500ms, this follows MSDN: + // https://msdn.microsoft.com/en-us/library/aa393691.aspx + // the resolution is higher, but it is not requested to be + + // Date was choosen from the example that made the problem visible + // in testing + Date testDate = new Date(2016 - 1900, 10 - 1, 12, 2, 59, 19); + + assertTrue("java.util.Date -> com.sun.jna.platform.win32.OaIdl.DATE -> java.util.Date roundtrip failed", + Math.abs(new DATE(testDate).getAsJavaDate().getTime() - testDate.getTime()) < 500); + } public void testVariantConstructors() { - VARIANT variant = new VARIANT((short) 1); - variant = new VARIANT((byte) 1); - variant = new VARIANT('1'); - variant = new VARIANT((int) 1); - variant = new VARIANT((long) 1); - variant = new VARIANT((float) 1); - variant = new VARIANT((double) 1); - variant = new VARIANT("1"); - variant = new VARIANT(true); - variant = new VARIANT(new Date()); + VARIANT variant; + + // skipped: BSTRByReference constructor + // skipped: empty constructor + // skipped: pointer constructor + // skipped: IDispatch constructor + String testString = "TeST$ö"; + BSTR bstr = OleAuto.INSTANCE.SysAllocString(testString); + + variant = new VARIANT(bstr); + assertThat(variant.getValue(), instanceOf(BSTR.class)); + assertThat(((BSTR)variant.getValue()).getValue(), equalTo(testString)); + assertThat(variant.stringValue(), equalTo(testString)); + + variant = new VARIANT(testString); + assertThat(variant.getValue(), instanceOf(BSTR.class)); + assertThat(((BSTR)variant.getValue()).getValue(), equalTo(testString)); + assertThat(variant.stringValue(), equalTo(testString)); + + OleAuto.INSTANCE.SysFreeString(bstr); + OleAuto.INSTANCE.SysFreeString((BSTR) variant.getValue()); + + BOOL boolTrue = new WinDef.BOOL(true); + + variant = new VARIANT(Variant.VARIANT_TRUE); + assertThat(variant.getValue(), instanceOf(VARIANT_BOOL.class)); + assertThat(((VARIANT_BOOL) variant.getValue()).shortValue(), equalTo((short) 0xFFFF)); + assertThat(variant.booleanValue(), equalTo(true)); + + variant = new VARIANT(boolTrue); + assertThat(variant.getValue(), instanceOf(VARIANT_BOOL.class)); + assertThat(((VARIANT_BOOL) variant.getValue()).shortValue(), equalTo((short) 0xFFFF)); + assertThat(variant.booleanValue(), equalTo(true)); + + int testInt = 4223; + LONG testIntWin = new LONG(testInt); + variant = new VARIANT(testIntWin); + assertThat(variant.getValue(), instanceOf(LONG.class)); + assertThat(((LONG) variant.getValue()).intValue(), equalTo(testInt)); + assertThat(variant.intValue(), equalTo(testInt)); + + variant = new VARIANT(testInt); + assertThat(variant.getValue(), instanceOf(LONG.class)); + assertThat(((LONG) variant.getValue()).intValue(), equalTo(testInt)); + assertThat(variant.intValue(), equalTo(testInt)); + + short testShort = 23; + SHORT testShortWin = new SHORT(testShort); + variant = new VARIANT(testShortWin); + assertThat(variant.getValue(), instanceOf(SHORT.class)); + assertThat(((SHORT) variant.getValue()).shortValue(), equalTo(testShort)); + assertThat(variant.shortValue(), equalTo(testShort)); + + variant = new VARIANT(testShort); + assertThat(variant.getValue(), instanceOf(SHORT.class)); + assertThat(((SHORT) variant.getValue()).shortValue(), equalTo(testShort)); + assertThat(variant.shortValue(), equalTo(testShort)); + + long testLong = 4223L + Integer.MAX_VALUE; + + variant = new VARIANT(testLong); + assertThat(variant.getValue(), instanceOf(LONGLONG.class)); + assertThat(((LONGLONG) variant.getValue()).longValue(), equalTo(testLong)); + assertThat(variant.longValue(), equalTo(testLong)); + + Date testDate = new Date(2042 - 1900, 2, 3, 23, 0, 0); + variant = new VARIANT(testDate); + assertThat(variant.getValue(), instanceOf(DATE.class)); + assertThat(variant.dateValue(), equalTo(testDate)); + + byte testByte = 42; + BYTE testByteWin = new BYTE(testByte); + CHAR testByteWin2 = new CHAR(testByte); + variant = new VARIANT(testByte); + assertThat(variant.getValue(), instanceOf(BYTE.class)); + assertThat(((BYTE) variant.getValue()).byteValue(), equalTo(testByte)); + assertThat(variant.byteValue(), equalTo(testByte)); + + variant = new VARIANT(testByteWin); + assertThat(variant.getValue(), instanceOf(BYTE.class)); + assertThat(((BYTE) variant.getValue()).byteValue(), equalTo(testByte)); + assertThat(variant.byteValue(), equalTo(testByte)); + + variant = new VARIANT(testByteWin2); + assertThat(variant.getValue(), instanceOf(CHAR.class)); + assertThat(((CHAR) variant.getValue()).byteValue(), equalTo(testByte)); + assertThat(variant.byteValue(), equalTo(testByte)); + + variant = new VARIANT(testByteWin2); + assertThat(variant.getValue(), instanceOf(CHAR.class)); + assertThat(((CHAR) variant.getValue()).byteValue(), equalTo(testByte)); + assertThat(variant.byteValue(), equalTo(testByte)); + + double testDouble = 42.23; + variant = new VARIANT(testDouble); + assertThat(variant.getValue(), instanceOf(Double.class)); + // If this fails introduce comparison with range + assertThat(variant.doubleValue(), equalTo(testDouble)); + + float testFloat = 42.23f; + variant = new VARIANT(testFloat); + assertThat(variant.getValue(), instanceOf(Float.class)); + // If this fails introduce comparison with range + assertThat(variant.floatValue(), equalTo(testFloat)); + + char testChar = 42 + Short.MAX_VALUE; + + variant = new VARIANT(testChar); + assertThat(variant.getValue(), instanceOf(USHORT.class)); + assertThat(((USHORT) variant.getValue()).intValue(), equalTo((int) testChar)); + assertThat(variant.intValue(), equalTo((int) testChar)); + } + + public void testVariantSafearrayWrapping() { + SAFEARRAY safearray = OaIdl.SAFEARRAY.createSafeArray(new VARTYPE(Variant.VT_I1), 5); + try { + VARIANT variant = new VARIANT(safearray); + assertThat(variant.getVarType().intValue(), equalTo((int) (Variant.VT_I1 | Variant.VT_ARRAY))); + Object wrappedValue = variant.getValue(); + assertThat(wrappedValue, instanceOf(SAFEARRAY.class)); + assertThat(safearray.getUBound(0), is(4)); + } finally { + safearray.destroy(); + } } } diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/VersionTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/VersionTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/VersionTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/VersionTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -15,6 +15,7 @@ import com.sun.jna.Pointer; import com.sun.jna.ptr.IntByReference; import com.sun.jna.ptr.PointerByReference; + import junit.framework.TestCase; public class VersionTest extends TestCase { @@ -25,33 +26,35 @@ public void testGetFileVersion() { String systemRoot = System.getenv("SystemRoot"); - File file = new File(systemRoot + "\\regedit.exe"); + assertNotNull("Missing system root environment variable", systemRoot); + File file = new File(systemRoot + File.separator + "regedit.exe"); if (!file.exists()) { fail("Can't obtain file version, file " + file + " is missing"); } - int size = Version.INSTANCE.GetFileVersionInfoSize(file.getAbsolutePath(), null); - assertTrue(size > 0); + String filePath = file.getAbsolutePath(); + int size = Version.INSTANCE.GetFileVersionInfoSize(filePath, null); + assertTrue("GetFileVersionInfoSize(" + filePath + ")", size > 0); Pointer buffer = Kernel32.INSTANCE.LocalAlloc(WinBase.LMEM_ZEROINIT, size); - assertTrue(!buffer.equals(Pointer.NULL)); + assertTrue("LocalAlloc(" + size + ")", !buffer.equals(Pointer.NULL)); - try - { - assertTrue(Version.INSTANCE.GetFileVersionInfo(file.getAbsolutePath(), 0, size, buffer)); + try { + assertTrue("GetFileVersionInfo(" + filePath + ")", + Version.INSTANCE.GetFileVersionInfo(filePath, 0, size, buffer)); IntByReference outputSize = new IntByReference(); PointerByReference pointer = new PointerByReference(); - assertTrue(Version.INSTANCE.VerQueryValue(buffer, "\\", pointer, outputSize)); + assertTrue("VerQueryValue", + Version.INSTANCE.VerQueryValue(buffer, "\\", pointer, outputSize)); - VerRsrc.VS_FIXEDFILEINFO fixedFileInfo = new VerRsrc.VS_FIXEDFILEINFO(pointer.getValue()); - assertTrue(fixedFileInfo.dwFileVersionLS.longValue() > 0); - assertTrue(fixedFileInfo.dwFileVersionMS.longValue() > 0); - } - finally - { - Kernel32.INSTANCE.GlobalFree(buffer); + VerRsrc.VS_FIXEDFILEINFO fixedFileInfo = + new VerRsrc.VS_FIXEDFILEINFO(pointer.getValue()); + assertTrue("dwFileVersionLS", fixedFileInfo.dwFileVersionLS.longValue() > 0); + assertTrue("dwFileVersionMS", fixedFileInfo.dwFileVersionMS.longValue() > 0); + } finally { + Kernel32Util.freeGlobalMemory(buffer); } } } diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/VersionUtilTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/VersionUtilTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/VersionUtilTest.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/VersionUtilTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,42 @@ +/* This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ +package com.sun.jna.platform.win32; + +import java.io.File; + +import com.sun.jna.platform.win32.VerRsrc.VS_FIXEDFILEINFO; + +import junit.framework.TestCase; + +public class VersionUtilTest extends TestCase { + + public static void main(String[] args) { + junit.textui.TestRunner.run(VersionUtilTest.class); + } + + public void testGetFileVersionNumbers() { + File file = new File(System.getenv("SystemRoot"), "regedit.exe"); + assertTrue("Test file with version info in it should exist: " + file, file.exists()); + + VS_FIXEDFILEINFO version = VersionUtil.getFileVersionInfo(file.getAbsolutePath()); + assertNotNull("Version info should have been returned.", version); + + assertTrue("The major file version number should be greater than 0 when pulling version from \"" + file + "\"", version.getFileVersionMajor() > 0); + assertTrue("The minor file version number should be greater than or equal to 0 when pulling version from \"" + file + "\"", version.getFileVersionMinor() >= 0); + assertTrue("The revision file version number should be greater than or equal to 0 when pulling version from \"" + file + "\"", version.getFileVersionRevision() >= 0); + assertTrue("The build file version number should be greater than or equal to 0 when pulling version from \"" + file + "\"", version.getFileVersionBuild() >= 0); + + assertTrue("The major product version number should be greater than 0 when pulling version from \"" + file + "\"", version.getProductVersionMajor() > 0); + assertTrue("The minor product version number should be greater than or equal to 0 when pulling version from \"" + file + "\"", version.getProductVersionMinor() >= 0); + assertTrue("The revision product version number should be greater than or equal to 0 when pulling version from \"" + file + "\"", version.getProductVersionRevision() >= 0); + assertTrue("The build product version number should be greater than or equal to 0 when pulling version from \"" + file + "\"", version.getProductVersionBuild() >= 0); + } +} diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/W32FileMonitorTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/W32FileMonitorTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/W32FileMonitorTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/W32FileMonitorTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -39,7 +39,7 @@ events = new HashMap(); final FileListener listener = new FileListener() { public void fileChanged(FileEvent e) { - events.put(new Integer(e.getType()), e); + events.put(Integer.valueOf(e.getType()), e); } }; monitor = FileMonitor.getInstance(); @@ -190,7 +190,7 @@ private FileEvent waitForFileEvent(final int expectedFileEvent) throws InterruptedException { - final Integer expectedFileEventInteger = new Integer(expectedFileEvent); + final Integer expectedFileEventInteger = Integer.valueOf(expectedFileEvent); FileEvent actualEvent = (FileEvent)events.get(expectedFileEventInteger); final long start = System.currentTimeMillis(); diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/W32ServiceTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/W32ServiceTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/W32ServiceTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/W32ServiceTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -13,9 +13,14 @@ package com.sun.jna.platform.win32; +import java.util.List; +import java.util.LinkedList; + import junit.framework.TestCase; +import com.sun.jna.platform.win32.Winsvc.SC_ACTION; import com.sun.jna.platform.win32.Winsvc.SERVICE_STATUS_PROCESS; +import com.sun.jna.platform.win32.Winsvc.SERVICE_FAILURE_ACTIONS; public class W32ServiceTest extends TestCase{ W32ServiceManager _serviceManager = new W32ServiceManager(); @@ -68,4 +73,68 @@ status.dwCurrentState == Winsvc.SERVICE_STOPPED); service.close(); } + + public void testSetAndGetFailureActions() { + final String svcId = "w32time"; + final String rebootMsg = "Restarting " + svcId + " due to service failure"; + final String command = "echo " + svcId + " failure"; + final int resetPeriod = 5000; + + W32Service service = _serviceManager.openService(svcId, Winsvc.SC_MANAGER_ALL_ACCESS); + SERVICE_FAILURE_ACTIONS prevActions = service.getFailureActions(); + + List actions = new LinkedList(); + + SC_ACTION action = new SC_ACTION(); + action.type = Winsvc.SC_ACTION_RESTART; + action.delay = 1000; + actions.add(action); + + action = new SC_ACTION(); + action.type = Winsvc.SC_ACTION_REBOOT; + action.delay = 2000; + actions.add(action); + + action = new SC_ACTION(); + action.type = Winsvc.SC_ACTION_RUN_COMMAND; + action.delay = 3000; + actions.add(action); + + action = new SC_ACTION(); + action.type = Winsvc.SC_ACTION_NONE; + action.delay = 4000; + actions.add(action); + + service.setFailureActions(actions, resetPeriod, rebootMsg, command); + + SERVICE_FAILURE_ACTIONS changedActions = service.getFailureActions(); + assertEquals(changedActions.lpRebootMsg, rebootMsg); + assertEquals(changedActions.lpCommand, command); + assertEquals(changedActions.dwResetPeriod, resetPeriod); + assertEquals(changedActions.cActions, 4); + SC_ACTION[] actionArray = (SC_ACTION[])changedActions.lpsaActions.toArray(changedActions.cActions); + assertEquals(actionArray[0].type, Winsvc.SC_ACTION_RESTART); + assertEquals(actionArray[0].delay, 1000); + assertEquals(actionArray[1].type, Winsvc.SC_ACTION_REBOOT); + assertEquals(actionArray[1].delay, 2000); + assertEquals(actionArray[2].type, Winsvc.SC_ACTION_RUN_COMMAND); + assertEquals(actionArray[2].delay, 3000); + assertEquals(actionArray[3].type, Winsvc.SC_ACTION_NONE); + assertEquals(actionArray[3].delay, 4000); + + // restore old settings + Advapi32.INSTANCE.ChangeServiceConfig2(service._handle, Winsvc.SERVICE_CONFIG_FAILURE_ACTIONS, + prevActions); + + service.close(); + } + + public void testSetFailureActionsFlag() { + W32Service service = _serviceManager.openService("eventlog", Winsvc.SC_MANAGER_ALL_ACCESS); + boolean prevFlag = service.getFailureActionsFlag(); + service.setFailureActionsFlag(!prevFlag); + assertTrue(prevFlag != service.getFailureActionsFlag()); + service.setFailureActionsFlag(prevFlag); + service.close(); + } } diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/WevtapiTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/WevtapiTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/WevtapiTest.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/WevtapiTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,597 @@ +/* Copyright (c) 2016 Minoru Sakamoto, 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.Memory; +import com.sun.jna.Native; +import com.sun.jna.platform.win32.WinDef.BOOL; +import com.sun.jna.platform.win32.Winevt.EVT_CHANNEL_CONFIG_PROPERTY_ID; +import com.sun.jna.platform.win32.Winevt.EVT_HANDLE; +import com.sun.jna.ptr.IntByReference; +import junit.framework.TestCase; + +import java.io.File; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertThat; + +/** + * @author Minoru Sakamoto + */ +public class WevtapiTest extends TestCase { + + public void testEvtGetExtendedStatus() throws Exception { + assertThat(_evtGetExtendedStatus(null).length(), is(0)); + assertThat(_evtGetExtendedStatus(">><").length() > 0, is(true)); // illegal query + } + + private String _evtGetExtendedStatus(String query) { + EVT_HANDLE handle = null; + String result; + try { + handle = Wevtapi.INSTANCE.EvtQuery(null, "Application", query, + Winevt.EVT_QUERY_FLAGS.EvtQueryChannelPath); + result = WevtapiUtil.EvtGetExtendedStatus(); + } finally { + if (handle != null) { + Wevtapi.INSTANCE.EvtClose(handle); + } + } + return result; + } + + public void testReadEvents() throws Exception { + EVT_HANDLE queryHandle = null; + EVT_HANDLE contextHandle = null; + File testEvtx = new File(getClass().getResource("/res/WevtapiTest.sample1.evtx").toURI()); + StringBuilder sb = new StringBuilder(); + try { + // test EvtQuery + queryHandle = Wevtapi.INSTANCE.EvtQuery(null, testEvtx.getPath(), null, + Winevt.EVT_QUERY_FLAGS.EvtQueryFilePath); + + // test EvtCreateRenderContext + String[] targets = {"Event/System/Provider/@Name", "Event/System/EventRecordID", "Event/System/EventID", "Event/EventData/Data", "Event/System/TimeCreated/@SystemTime"}; + contextHandle = Wevtapi.INSTANCE.EvtCreateRenderContext(targets.length, targets, + Winevt.EVT_RENDER_CONTEXT_FLAGS.EvtRenderContextValues); + + // test EvtNext + int eventArraySize = 10; + int evtNextTimeout = 1000; + int arrayIndex = 0; + EVT_HANDLE[] eventArray = new EVT_HANDLE[eventArraySize]; + IntByReference returned = new IntByReference(); + + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + + while (Wevtapi.INSTANCE.EvtNext(queryHandle, eventArraySize, eventArray, evtNextTimeout, 0, returned)) { + + // test EvtRender + Memory buff; + IntByReference propertyCount = new IntByReference(); + Winevt.EVT_VARIANT evtVariant = new Winevt.EVT_VARIANT(); + for (int i = 0; i < returned.getValue(); i++) { + buff = WevtapiUtil.EvtRender(contextHandle, eventArray[i], Winevt.EVT_RENDER_FLAGS.EvtRenderEventValues, propertyCount); + assertThat("PropertyCount", propertyCount.getValue(), is(5)); + useMemory(evtVariant, buff, 0); + assertThat("Provider Name", (String) evtVariant.getValue(), is("testSource")); + sb.append((String) evtVariant.getValue()); + useMemory(evtVariant, buff, 1); + assertThat("EventRecordID", (Long) evtVariant.getValue(), is((long) arrayIndex * eventArraySize + i + 1)); + useMemory(evtVariant, buff, 2); + assertThat("EventID", (Short) evtVariant.getValue(), is((short) (5000 + (arrayIndex * eventArraySize + i + 1)))); + useMemory(evtVariant, buff, 3); + String[] args = (String[]) evtVariant.getValue(); + assertThat("Data#length", args.length, is(1)); + assertThat("Data#value", args[0], is("testMessage" + (arrayIndex * eventArraySize + i + 1))); + useMemory(evtVariant, buff, 4); + Date systemtime = ((WinBase.FILETIME) evtVariant.getValue()).toDate(); + assertThat("TimeCreated", dateFormat.format(systemtime), is("2016-08-17")); + } + arrayIndex++; + } + if (Kernel32.INSTANCE.GetLastError() != WinError.ERROR_SUCCESS && + Kernel32.INSTANCE.GetLastError() != WinError.ERROR_NO_MORE_ITEMS) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + assertThat(sb.length() > 0, is(true)); + } finally { + // test EvtClose + if (queryHandle != null) { + Wevtapi.INSTANCE.EvtClose(queryHandle); + } + if (contextHandle != null) { + Wevtapi.INSTANCE.EvtClose(contextHandle); + } + } + + // =========== Test accessing binary data and empty value ================ + + queryHandle = null; + contextHandle = null; + testEvtx = new File(getClass().getResource("/res/WevtapiTest.sample2.evtx").toURI()); + try { + queryHandle = Wevtapi.INSTANCE.EvtQuery(null, testEvtx.getPath(), null, + Winevt.EVT_QUERY_FLAGS.EvtQueryFilePath); + + String[] targets = {"Event/EventData/Binary", "Event/System/Correlation"}; + contextHandle = Wevtapi.INSTANCE.EvtCreateRenderContext(targets.length, targets, + Winevt.EVT_RENDER_CONTEXT_FLAGS.EvtRenderContextValues); + + int read = 0; + int eventArraySize = 1; + int evtNextTimeout = 1000; + EVT_HANDLE[] eventArray = new EVT_HANDLE[eventArraySize]; + IntByReference returned = new IntByReference(); + + while (Wevtapi.INSTANCE.EvtNext(queryHandle, eventArraySize, eventArray, evtNextTimeout, 0, returned)) { + Memory buff; + IntByReference propertyCount = new IntByReference(); + Winevt.EVT_VARIANT evtVariant = new Winevt.EVT_VARIANT(); + for (int i = 0; i < returned.getValue(); i++) { + read++; + buff = WevtapiUtil.EvtRender(contextHandle, eventArray[i], Winevt.EVT_RENDER_FLAGS.EvtRenderEventValues, propertyCount); + assertThat("PropertyCount", propertyCount.getValue(), is(2)); + useMemory(evtVariant, buff, 0); + assertThat("Binary", (byte[]) evtVariant.getValue(), is(new byte[]{(byte) 0xD9, (byte) 0x06, 0, 0})); + useMemory(evtVariant, buff, 1); + assertThat("Correlation", evtVariant.getValue(), nullValue()); + } + } + + assertThat(read, is(1)); + } finally { + // test EvtClose + if (queryHandle != null) { + Wevtapi.INSTANCE.EvtClose(queryHandle); + } + if (contextHandle != null) { + Wevtapi.INSTANCE.EvtClose(contextHandle); + } + } + + // =========== Test accessing GUID + SID data ================ + + queryHandle = null; + contextHandle = null; + testEvtx = new File(getClass().getResource("/res/WevtapiTest.sample3.evtx").toURI()); + try { + queryHandle = Wevtapi.INSTANCE.EvtQuery(null, testEvtx.getPath(), null, + Winevt.EVT_QUERY_FLAGS.EvtQueryFilePath); + + String[] targets = {"Event/System/Security/@UserID", "Event/System/Provider/@Guid"}; + contextHandle = Wevtapi.INSTANCE.EvtCreateRenderContext(targets.length, targets, + Winevt.EVT_RENDER_CONTEXT_FLAGS.EvtRenderContextValues); + + int read = 0; + int eventArraySize = 1; + int evtNextTimeout = 1000; + EVT_HANDLE[] eventArray = new EVT_HANDLE[eventArraySize]; + IntByReference returned = new IntByReference(); + + while (Wevtapi.INSTANCE.EvtNext(queryHandle, eventArraySize, eventArray, evtNextTimeout, 0, returned)) { + Memory buff; + IntByReference propertyCount = new IntByReference(); + Winevt.EVT_VARIANT evtVariant = new Winevt.EVT_VARIANT(); + for (int i = 0; i < returned.getValue(); i++) { + read++; + buff = WevtapiUtil.EvtRender(contextHandle, eventArray[i], Winevt.EVT_RENDER_FLAGS.EvtRenderEventValues, propertyCount); + assertThat("PropertyCount", propertyCount.getValue(), is(2)); + useMemory(evtVariant, buff, 0); + assertThat("Security#UserID", ((WinNT.PSID) evtVariant.getValue()).getSidString(), is("S-1-5-21-3178902164-3053647283-518304804-1001")); + useMemory(evtVariant, buff, 1); + assertThat("Provider#GUID", ((Guid.GUID) evtVariant.getValue()).toGuidString(), is("{B0AA8734-56F7-41CC-B2F4-DE228E98B946}")); + } + } + + assertThat(read, is(1)); + } finally { + // test EvtClose + if (queryHandle != null) { + Wevtapi.INSTANCE.EvtClose(queryHandle); + } + if (contextHandle != null) { + Wevtapi.INSTANCE.EvtClose(contextHandle); + } + } + } + + private void useMemory(Winevt.EVT_VARIANT evtVariant, Memory buff, int index) { + evtVariant.use(buff.share(evtVariant.size() * index)); + evtVariant.read(); + } + + + public void testEvtOpenLog() throws Exception { + File testEvtx = new File(getClass().getResource("/res/WevtapiTest.sample1.evtx").toURI()); + EVT_HANDLE logHandle = Wevtapi.INSTANCE.EvtOpenLog(null, testEvtx.getAbsolutePath(), + Winevt.EVT_OPEN_LOG_FLAGS.EvtOpenFilePath); + if (logHandle == null) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + Memory buff = new Memory(1024); + IntByReference buffUsed = new IntByReference(); + if (!Wevtapi.INSTANCE.EvtGetLogInfo(logHandle, Winevt.EVT_LOG_PROPERTY_ID.EvtLogFileSize, (int) buff.size(), buff, buffUsed)) { + if (Kernel32.INSTANCE.GetLastError() == WinError.ERROR_INSUFFICIENT_BUFFER) { + buff = new Memory(buffUsed.getValue()); + if (!Wevtapi.INSTANCE.EvtGetLogInfo(logHandle, Winevt.EVT_LOG_PROPERTY_ID.EvtLogFileSize, (int) buff.size(), buff, buffUsed)) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + } else { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + } + assertThat(buff.getLong(0), is(69632L)); + } + + + public void testEvtOpenChannelEnum() throws Exception { + + EVT_HANDLE channelHandle = null; + List channelList = new ArrayList(); + try { + channelHandle = Wevtapi.INSTANCE.EvtOpenChannelEnum(null, 0); + if (channelHandle == null) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + char[] buff = new char[1024]; + IntByReference buffUsed = new IntByReference(); + while (true) { + if (!Wevtapi.INSTANCE.EvtNextChannelPath(channelHandle, buff.length, buff, buffUsed)) { + if (Kernel32.INSTANCE.GetLastError() == WinError.ERROR_NO_MORE_ITEMS) { + break; + } else if (Kernel32.INSTANCE.GetLastError() == WinError.ERROR_INSUFFICIENT_BUFFER) { + buff = new char[buffUsed.getValue()]; + if (!Wevtapi.INSTANCE.EvtNextChannelPath(channelHandle, buff.length, buff, buffUsed)) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + } + } + channelList.add(Native.toString(buff)); + } + assertThat(channelList.size() > 0, is(true)); + + } finally { + if (channelHandle != null) { + Wevtapi.INSTANCE.EvtClose(channelHandle); + } + } + } + + public void testEvtOpenChannelConfig() throws Exception { + EVT_HANDLE channelHandle = null; + try { + channelHandle = Wevtapi.INSTANCE.EvtOpenChannelConfig(null, "Application", 0); + assertNotNull(channelHandle); + Winevt.EVT_VARIANT evtVariant = WevtapiUtil.EvtGetChannelConfigProperty(channelHandle, + Winevt.EVT_CHANNEL_CONFIG_PROPERTY_ID.EvtChannelConfigClassicEventlog); + assertThat(((WinDef.BOOL) evtVariant.getValue()).booleanValue(), is(true)); + } finally { + if (channelHandle != null) { + Wevtapi.INSTANCE.EvtClose(channelHandle); + } + } + } + + public void testModifyChannelConfig() throws Exception { + EVT_HANDLE channelHandle = null; + try { + channelHandle = Wevtapi.INSTANCE.EvtOpenChannelConfig(null, "Application", 0); + assertNotNull(channelHandle); + + Winevt.EVT_VARIANT evtVariant = WevtapiUtil.EvtGetChannelConfigProperty(channelHandle, EVT_CHANNEL_CONFIG_PROPERTY_ID.EvtChannelConfigClassicEventlog); + assertThat(((WinDef.BOOL) evtVariant.getValue()).booleanValue(), is(true)); + + Winevt.EVT_VARIANT setter = new Winevt.EVT_VARIANT(); + setter.setValue(Winevt.EVT_VARIANT_TYPE.EvtVarTypeBoolean, new BOOL(false)); + Wevtapi.INSTANCE.EvtSetChannelConfigProperty(channelHandle, EVT_CHANNEL_CONFIG_PROPERTY_ID.EvtChannelConfigClassicEventlog, 0, setter); + + evtVariant = WevtapiUtil.EvtGetChannelConfigProperty(channelHandle, EVT_CHANNEL_CONFIG_PROPERTY_ID.EvtChannelConfigClassicEventlog); + assertThat(((WinDef.BOOL) evtVariant.getValue()).booleanValue(), is(false)); + + setter.setValue(Winevt.EVT_VARIANT_TYPE.EvtVarTypeBoolean, new BOOL(true)); + Wevtapi.INSTANCE.EvtSetChannelConfigProperty(channelHandle, EVT_CHANNEL_CONFIG_PROPERTY_ID.EvtChannelConfigClassicEventlog, 0, setter); + + evtVariant = WevtapiUtil.EvtGetChannelConfigProperty(channelHandle, EVT_CHANNEL_CONFIG_PROPERTY_ID.EvtChannelConfigClassicEventlog); + assertThat(((WinDef.BOOL) evtVariant.getValue()).booleanValue(), is(true)); + + // Writing back is skipped neighter is EvtChannelConfigClassicEventlog + // writable, nor is it a good idea to mess with the log of the developer machine + } finally { + if (channelHandle != null) { + Wevtapi.INSTANCE.EvtClose(channelHandle); + } + } + } + + public void testEvtOpenPublisherEnum() throws Exception { + Winevt.EVT_RPC_LOGIN login = new Winevt.EVT_RPC_LOGIN("localhost", null, null, null, + Winevt.EVT_RPC_LOGIN_FLAGS.EvtRpcLoginAuthDefault); + EVT_HANDLE session = null; + EVT_HANDLE publisherEnumHandle = null; + List publisherList = new ArrayList(); + try { + session = Wevtapi.INSTANCE.EvtOpenSession(Winevt.EVT_LOGIN_CLASS.EvtRpcLogin, login, 0, 0); + if (session == null) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + publisherEnumHandle = Wevtapi.INSTANCE.EvtOpenPublisherEnum(session, 0); + if (publisherEnumHandle == null) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + String providerName; + while (true) { + try { + providerName = WevtapiUtil.EvtNextPublisherId(publisherEnumHandle); + } catch (Win32Exception e) { + if (e.getErrorCode() == WinError.ERROR_NO_MORE_ITEMS) { + break; + } else { + throw e; + } + } + publisherList.add(providerName); + } + assertThat(publisherList.size() > 0, is(true)); + } finally { + if (publisherEnumHandle != null) { + Wevtapi.INSTANCE.EvtClose(publisherEnumHandle); + } + + if (session != null) { + Wevtapi.INSTANCE.EvtClose(session); + } + + } + } + + public void testEvtGetQueryInfo() throws Exception { + EVT_HANDLE queryHandle = null; + try { + queryHandle = Wevtapi.INSTANCE.EvtQuery(null, "Application", null, + Winevt.EVT_QUERY_FLAGS.EvtQueryChannelPath); + + Memory buff = new Memory(1024); + IntByReference bufferUsed = new IntByReference(); + if (!Wevtapi.INSTANCE.EvtGetQueryInfo(queryHandle, Winevt.EVT_QUERY_PROPERTY_ID.EvtQueryNames, (int) buff.size(), buff, bufferUsed)) { + if (Kernel32.INSTANCE.GetLastError() == WinError.ERROR_INSUFFICIENT_BUFFER) { + buff = new Memory(bufferUsed.getValue()); + if (!Wevtapi.INSTANCE.EvtGetQueryInfo(queryHandle, Winevt.EVT_QUERY_PROPERTY_ID.EvtQueryNames, (int) buff.size(), buff, bufferUsed)) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + } + } + Winevt.EVT_VARIANT evtVariant = new Winevt.EVT_VARIANT(buff.share(0)); + evtVariant.readField("Type"); + StringBuilder sb = new StringBuilder(); + + evtVariant.readField("Count"); + int count = evtVariant.Count; + useMemory(evtVariant, buff, 0); + String[] queryNames = (String[]) evtVariant.getValue(); + for (int i = 0; i < count; i++) { + sb.append(queryNames[i]); + } + assertThat(sb.toString(), is("Application")); + } finally { + if (queryHandle != null) { + Wevtapi.INSTANCE.EvtClose(queryHandle); + } + } + } + + public void testEvtCreateBookmark() throws Exception { + EVT_HANDLE queryHandle = null; + EVT_HANDLE contextHandle = null; + File testEvtx = new File(getClass().getResource("/res/WevtapiTest.sample1.evtx").toURI()); + StringBuilder sb = new StringBuilder(); + try { + queryHandle = Wevtapi.INSTANCE.EvtQuery(null, testEvtx.getPath(), null, + Winevt.EVT_QUERY_FLAGS.EvtQueryFilePath); + + // test EvtCreateBookmark + EVT_HANDLE hBookmark = Wevtapi.INSTANCE.EvtCreateBookmark( + "" + ); + if (hBookmark == null) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + // test EvtSeek + if (!Wevtapi.INSTANCE.EvtSeek(queryHandle, 0L, hBookmark, 0, Winevt.EVT_SEEK_FLAGS.EvtSeekRelativeToBookmark)) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + String[] targets = {"Event/System/EventRecordID"}; + contextHandle = Wevtapi.INSTANCE.EvtCreateRenderContext(targets.length, targets, + Winevt.EVT_RENDER_CONTEXT_FLAGS.EvtRenderContextValues); + + int eventArraySize = 10; + int evtNextTimeout = 1000; + int arrayIndex = 1; + Memory buff; + IntByReference propertyCount = new IntByReference(); + Winevt.EVT_VARIANT evtVariant = new Winevt.EVT_VARIANT(); + EVT_HANDLE[] eventArray = new EVT_HANDLE[eventArraySize]; + IntByReference returned = new IntByReference(); + while (Wevtapi.INSTANCE.EvtNext(queryHandle, eventArraySize, eventArray, evtNextTimeout, 0, returned)) { + for (int i = 0; i < returned.getValue(); i++) { + EVT_HANDLE evtHandle = eventArray[i]; + try { + buff = WevtapiUtil.EvtRender(contextHandle, eventArray[i], Winevt.EVT_RENDER_FLAGS.EvtRenderEventValues, propertyCount); + useMemory(evtVariant, buff, 0); + assertThat("EventRecordID", (Long) evtVariant.getValue(), is((long) arrayIndex * eventArraySize + i + 1)); + sb.append(evtVariant.getValue()); + + // test EvtUpdateBookmark + if (!Wevtapi.INSTANCE.EvtUpdateBookmark(hBookmark, eventArray[i])) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + } finally { + if (eventArray[i] != null) { + Wevtapi.INSTANCE.EvtClose(eventArray[i]); + } + } + } + arrayIndex++; + } + if (Kernel32.INSTANCE.GetLastError() != WinError.ERROR_SUCCESS && + Kernel32.INSTANCE.GetLastError() != WinError.ERROR_NO_MORE_ITEMS) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + buff = WevtapiUtil.EvtRender(null, hBookmark, Winevt.EVT_RENDER_FLAGS.EvtRenderBookmark, propertyCount); + assertThat(buff.getWideString(0), is("\r\n \r\n")); + assertThat(sb.length() > 0, is(true)); + } finally { + if (queryHandle != null) { + Wevtapi.INSTANCE.EvtClose(queryHandle); + } + if (contextHandle != null) { + Wevtapi.INSTANCE.EvtClose(contextHandle); + } + } + } + + public void testEvtGetEventInfo() throws Exception { + EVT_HANDLE queryHandle = null; + EVT_HANDLE contextHandle = null; + File testEvtx = new File(getClass().getResource("/res/WevtapiTest.sample1.evtx").toURI()); + StringBuilder sb = new StringBuilder(); + try { + queryHandle = Wevtapi.INSTANCE.EvtQuery(null, testEvtx.getPath(), null, + Winevt.EVT_QUERY_FLAGS.EvtQueryFilePath); + + + String[] targets = {"Event/System/EventRecordID"}; + contextHandle = Wevtapi.INSTANCE.EvtCreateRenderContext(targets.length, targets, + Winevt.EVT_RENDER_CONTEXT_FLAGS.EvtRenderContextValues); + + int eventArraySize = 10; + int evtNextTimeout = 1000; + Memory buff = new Memory(1024); + Winevt.EVT_VARIANT evtVariant = new Winevt.EVT_VARIANT(); + EVT_HANDLE[] eventArray = new EVT_HANDLE[eventArraySize]; + IntByReference buffUsed = new IntByReference(); + IntByReference returned = new IntByReference(); + while (Wevtapi.INSTANCE.EvtNext(queryHandle, eventArraySize, eventArray, evtNextTimeout, 0, returned)) { + for (int i = 0; i < returned.getValue(); i++) { + try { + if (!Wevtapi.INSTANCE.EvtGetEventInfo(eventArray[i], + Winevt.EVT_EVENT_PROPERTY_ID.EvtEventPath, (int) buff.size(), buff, buffUsed)) { + if (Kernel32.INSTANCE.GetLastError() == WinError.ERROR_INSUFFICIENT_BUFFER) { + buff = new Memory(buffUsed.getValue()); + if (!Wevtapi.INSTANCE.EvtGetEventInfo(eventArray[i], + Winevt.EVT_EVENT_PROPERTY_ID.EvtEventPath, (int) buff.size(), buff, buffUsed)) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + } + } + useMemory(evtVariant, buff, 0); + assertThat("Evtx Path", (String) evtVariant.getValue(), is(testEvtx.getAbsolutePath())); + sb.append((String) evtVariant.getValue()); + } finally { + if (eventArray[i] != null) { + Wevtapi.INSTANCE.EvtClose(eventArray[i]); + } + } + + } + + } + if (Kernel32.INSTANCE.GetLastError() != WinError.ERROR_SUCCESS && + Kernel32.INSTANCE.GetLastError() != WinError.ERROR_NO_MORE_ITEMS) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + assertThat(sb.length() > 0, is(true)); + } finally { + if (queryHandle != null) { + Wevtapi.INSTANCE.EvtClose(queryHandle); + } + if (contextHandle != null) { + Wevtapi.INSTANCE.EvtClose(contextHandle); + } + } + } + + public void testEvtVariantType() throws Exception { + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeNull.getField(), is("")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeString.getField(), is("StringVal")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeAnsiString.getField(), is("AnsiStringVal")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeSByte.getField(), is("SByteVal")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeByte.getField(), is("ByteVal")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeInt16.getField(), is("Int16Val")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeUInt16.getField(), is("UInt16Val")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeInt32.getField(), is("Int32Val")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeUInt32.getField(), is("UInt32Val")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeInt64.getField(), is("Int64Val")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeUInt64.getField(), is("UInt64Val")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeSingle.getField(), is("SingleVal")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeDouble.getField(), is("DoubleVal")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeBoolean.getField(), is("BooleanVal")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeBinary.getField(), is("BinaryVal")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeGuid.getField(), is("GuidVal")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeSizeT.getField(), is("SizeTVal")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeFileTime.getField(), is("FileTimeVal")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeSysTime.getField(), is("SysTimeVal")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeSid.getField(), is("SidVal")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeHexInt32.getField(), is("Int32Val")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeHexInt64.getField(), is("Int64Val")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeEvtHandle.getField(), is("EvtHandleVal")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeEvtXml.getField(), is("XmlVal")); + + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeNull.getArrField(), is("")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeString.getArrField(), is("StringArr")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeAnsiString.getArrField(), is("AnsiStringArr")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeSByte.getArrField(), is("SByteArr")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeByte.getArrField(), is("ByteArr")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeInt16.getArrField(), is("Int16Arr")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeUInt16.getArrField(), is("UInt16Arr")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeInt32.getArrField(), is("Int32Arr")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeUInt32.getArrField(), is("UInt32Arr")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeInt64.getArrField(), is("Int64Arr")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeUInt64.getArrField(), is("UInt64Arr")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeSingle.getArrField(), is("SingleArr")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeDouble.getArrField(), is("DoubleArr")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeBoolean.getArrField(), is("BooleanArr")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeBinary.getArrField(), is("BinaryArr")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeGuid.getArrField(), is("GuidArr")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeSizeT.getArrField(), is("SizeTArr")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeFileTime.getArrField(), is("FileTimeArr")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeSysTime.getArrField(), is("SysTimeArr")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeSid.getArrField(), is("SidArr")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeHexInt32.getArrField(), is("Int32Arr")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeHexInt64.getArrField(), is("Int64Arr")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeEvtHandle.getArrField(), is("EvtHandleArr")); + assertThat(Winevt.EVT_VARIANT_TYPE.EvtVarTypeEvtXml.getArrField(), is("XmlArr")); + + } +} \ No newline at end of file diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/Win32ExceptionTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/Win32ExceptionTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/Win32ExceptionTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/Win32ExceptionTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,17 +1,19 @@ /* Copyright (c) 2010 Daniel Doubrovkine, All Rights Reserved - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * Lesser General Public License for more details. */ package com.sun.jna.platform.win32; +import com.sun.jna.LastErrorException; + import junit.framework.TestCase; /** @@ -23,21 +25,33 @@ junit.textui.TestRunner.run(Win32ExceptionTest.class); } - public void testFormatMessageFromLastErrorCode() { - try { - throw new Win32Exception(W32Errors.ERROR_SHARING_PAUSED); - } catch (Win32Exception e) { - assertEquals("The remote server has been paused or is in the process of being started.", - e.getMessage()); - } - } - - public void testFormatMessageFromHR() { - try { - throw new Win32Exception(W32Errors.S_OK); - } catch (Win32Exception e) { - assertEquals("The operation completed successfully.", - e.getMessage()); - } - } + public void testFormatMessageFromLastErrorCode() { + try { + throw new Win32Exception(W32Errors.ERROR_SHARING_PAUSED); + } catch (Win32Exception e) { + if(AbstractWin32TestSupport.isEnglishLocale) { + assertLastErrorValue(e, W32Errors.ERROR_SHARING_PAUSED, + "The remote server has been paused or is in the process of being started."); + } else { + System.err.println("testFormatMessageFromHR test can only be run with english locale."); + } + } + } + + public void testFormatMessageFromHR() { + try { + throw new Win32Exception(W32Errors.S_OK); + } catch (Win32Exception e) { + if(AbstractWin32TestSupport.isEnglishLocale) { + assertLastErrorValue(e, W32Errors.ERROR_SUCCESS, "The operation completed successfully."); + } else { + System.err.println("testFormatMessageFromHR test can only be run with english locale."); + } + } + } + + private void assertLastErrorValue(LastErrorException e, int code, String msg) { + assertEquals("Mismatched error code", code, e.getErrorCode()); + assertEquals("Mismatched error message", msg, e.getMessage()); + } } diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/WinBaseTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/WinBaseTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/WinBaseTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/WinBaseTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,133 +1,192 @@ /* Copyright (c) 2015 Markus Bollig, All Rights Reserved - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * Lesser General Public License for more details. */ package com.sun.jna.platform.win32; +import java.util.Calendar; +import java.util.Date; + import com.sun.jna.platform.win32.WinBase.DCB; +import com.sun.jna.platform.win32.WinBase.FILETIME; +import com.sun.jna.platform.win32.WinBase.SYSTEMTIME; import junit.framework.TestCase; public class WinBaseTest extends TestCase { + public WinBaseTest() { + super(); + } + + public WinBaseTest(String name) { + super(name); + } + + public void testFiletime() { + // subtract to convert ms after 1/1/1970 to ms after 1/1/1601 + long epochDiff = 11644473600000L; + // Construct filetimes for ms after 1/1/1601, check for 100-ns after + assertEquals("Mismatched filetime for 2ms", (new FILETIME(new Date(2L - epochDiff))).toDWordLong().longValue(), 2L * 10000); + assertEquals("Mismatched filetime for 2^16ms", (new FILETIME(new Date((1L << 16) - epochDiff))).toDWordLong().longValue(), (1L << 16) * 10000); + assertEquals("Mismatched filetime for 2^32ms", (new FILETIME(new Date((1L << 32) - epochDiff))).toDWordLong().longValue(), (1L << 32) * 10000); + assertEquals("Mismatched filetime for 2^49ms", (new FILETIME(new Date((1L << 49) - epochDiff))).toDWordLong().longValue(), (1L << 49) * 10000); + } + + public void testCalendarToSystemTimeConversion() { + Calendar expected = Calendar.getInstance(); + SYSTEMTIME sysTime = new SYSTEMTIME(); + sysTime.fromCalendar(expected); + + assertEquals("Mismatched systime year", expected.get(Calendar.YEAR), sysTime.wYear); + assertEquals("Mismatched systime month", (1 + expected.get(Calendar.MONTH) - Calendar.JANUARY), sysTime.wMonth); + assertEquals("Mismatched systime day", expected.get(Calendar.DAY_OF_MONTH), sysTime.wDay); + assertEquals("Mismatched systime weekday", expected.get(Calendar.DAY_OF_WEEK) - Calendar.SUNDAY, sysTime.wDayOfWeek); + + assertEquals("Mismatched systime hour", expected.get(Calendar.HOUR_OF_DAY), sysTime.wHour); + assertEquals("Mismatched systime minute", expected.get(Calendar.MINUTE), sysTime.wMinute); + assertEquals("Mismatched systime second", expected.get(Calendar.SECOND), sysTime.wSecond); + // NOTE: we do not check millis due to clock granularity issues + + Calendar actual = sysTime.toCalendar(); + assertEquals("Mismatched calendar year", sysTime.wYear, actual.get(Calendar.YEAR)); + assertEquals("Mismatched calendar month", Calendar.JANUARY + (sysTime.wMonth - 1), actual.get(Calendar.MONTH)); + assertEquals("Mismatched calendar day", sysTime.wDay, actual.get(Calendar.DAY_OF_MONTH)); + assertEquals("Mismatched calendar weekday", sysTime.wDayOfWeek, actual.get(Calendar.DAY_OF_WEEK) - Calendar.SUNDAY); + + assertEquals("Mismatched calendar hour", sysTime.wHour, actual.get(Calendar.HOUR_OF_DAY)); + assertEquals("Mismatched calendar minute", sysTime.wMinute, actual.get(Calendar.MINUTE)); + assertEquals("Mismatched calendar second", sysTime.wSecond, actual.get(Calendar.SECOND)); + // NOTE: we do not check millis due to clock granularity issues + + assertEquals("Mismatched reconstructed year", expected.get(Calendar.YEAR), actual.get(Calendar.YEAR)); + assertEquals("Mismatched reconstructed month", expected.get(Calendar.MONTH), actual.get(Calendar.MONTH)); + assertEquals("Mismatched reconstructed day", expected.get(Calendar.DAY_OF_MONTH), actual.get(Calendar.DAY_OF_MONTH)); + assertEquals("Mismatched reconstructed weekday", expected.get(Calendar.DAY_OF_WEEK), actual.get(Calendar.DAY_OF_WEEK)); + + assertEquals("Mismatched reconstructed hour", expected.get(Calendar.HOUR_OF_DAY), actual.get(Calendar.HOUR_OF_DAY)); + assertEquals("Mismatched reconstructed minute", expected.get(Calendar.MINUTE), actual.get(Calendar.MINUTE)); + assertEquals("Mismatched reconstructed second", expected.get(Calendar.SECOND), actual.get(Calendar.SECOND)); + // NOTE: we do not check millis due to clock granularity issues + } - /** - * Test the mapping of the {@link DCB} structure. - * Particularly the mapping of the bit field is tested. - */ + /** + * Test the mapping of the {@link DCB} structure. + * Particularly the mapping of the bit field is tested. + */ public void testDCBStructureMapping() { - //first we test if the WinBase.DCB bitfiled mapping works as expected. - WinBase.DCB lpDCB = new WinBase.DCB(); - lpDCB.controllBits.setValue(0); - - lpDCB.controllBits.setfBinary(true); - assertEquals(1, lpDCB.controllBits.longValue()); - assertEquals(true, lpDCB.controllBits.getfBinary()); - lpDCB.controllBits.setfBinary(false); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(false, lpDCB.controllBits.getfBinary()); - - lpDCB.controllBits.setfParity(true); - assertEquals(2, lpDCB.controllBits.longValue()); - assertEquals(true, lpDCB.controllBits.getfParity()); - lpDCB.controllBits.setfParity(false); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(false, lpDCB.controllBits.getfParity()); - - lpDCB.controllBits.setfOutxCtsFlow(true); - assertEquals(4, lpDCB.controllBits.longValue()); - assertEquals(true, lpDCB.controllBits.getfOutxCtsFlow()); - lpDCB.controllBits.setfOutxCtsFlow(false); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(false, lpDCB.controllBits.getfOutxCtsFlow()); - - lpDCB.controllBits.setfOutxDsrFlow(true); - assertEquals(8, lpDCB.controllBits.longValue()); - assertEquals(true, lpDCB.controllBits.getfOutxDsrFlow()); - lpDCB.controllBits.setfOutxDsrFlow(false); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(false, lpDCB.controllBits.getfOutxDsrFlow()); - - lpDCB.controllBits.setfDtrControl(WinBase.DTR_CONTROL_ENABLE); - assertEquals(16, lpDCB.controllBits.longValue()); - assertEquals(WinBase.DTR_CONTROL_ENABLE, lpDCB.controllBits.getfDtrControl()); - lpDCB.controllBits.setfDtrControl(WinBase.DTR_CONTROL_HANDSHAKE); - assertEquals(32, lpDCB.controllBits.longValue()); - assertEquals(WinBase.DTR_CONTROL_HANDSHAKE, lpDCB.controllBits.getfDtrControl()); - lpDCB.controllBits.setfDtrControl(WinBase.DTR_CONTROL_DISABLE); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(WinBase.DTR_CONTROL_DISABLE, lpDCB.controllBits.getfDtrControl()); - - lpDCB.controllBits.setfDsrSensitivity(true); - assertEquals(64, lpDCB.controllBits.longValue()); - assertEquals(true, lpDCB.controllBits.getfDsrSensitivity()); - lpDCB.controllBits.setfDsrSensitivity(false); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(false, lpDCB.controllBits.getfDsrSensitivity()); - - lpDCB.controllBits.setfTXContinueOnXoff(true); - assertEquals(128, lpDCB.controllBits.longValue()); - assertEquals(true, lpDCB.controllBits.getfTXContinueOnXoff()); - lpDCB.controllBits.setfTXContinueOnXoff(false); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(false, lpDCB.controllBits.getfTXContinueOnXoff()); - - lpDCB.controllBits.setfOutX(true); - assertEquals(256, lpDCB.controllBits.longValue()); - assertEquals(true, lpDCB.controllBits.getfOutX()); - lpDCB.controllBits.setfOutX(false); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(false, lpDCB.controllBits.getfOutX()); - - lpDCB.controllBits.setfInX(true); - assertEquals(512, lpDCB.controllBits.longValue()); - assertEquals(true, lpDCB.controllBits.getfInX()); - lpDCB.controllBits.setfInX(false); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(false, lpDCB.controllBits.getfInX()); - - lpDCB.controllBits.setfErrorChar(true); - assertEquals(1024, lpDCB.controllBits.longValue()); - assertEquals(true, lpDCB.controllBits.getfErrorChar()); - lpDCB.controllBits.setfErrorChar(false); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(false, lpDCB.controllBits.getfErrorChar()); - - lpDCB.controllBits.setfNull(true); - assertEquals(2048, lpDCB.controllBits.longValue()); - assertEquals(true, lpDCB.controllBits.getfNull()); - lpDCB.controllBits.setfNull(false); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(false, lpDCB.controllBits.getfNull()); - - - lpDCB.controllBits.setfRtsControl(WinBase.RTS_CONTROL_ENABLE); - assertEquals(4096, lpDCB.controllBits.longValue()); - assertEquals(WinBase.RTS_CONTROL_ENABLE, lpDCB.controllBits.getfRtsControl()); - lpDCB.controllBits.setfRtsControl(WinBase.RTS_CONTROL_HANDSHAKE); - assertEquals(8192, lpDCB.controllBits.longValue()); - assertEquals(WinBase.RTS_CONTROL_HANDSHAKE, lpDCB.controllBits.getfRtsControl()); - lpDCB.controllBits.setfRtsControl(WinBase.RTS_CONTROL_TOGGLE); - assertEquals(12288, lpDCB.controllBits.longValue()); - assertEquals(WinBase.RTS_CONTROL_TOGGLE, lpDCB.controllBits.getfRtsControl()); - lpDCB.controllBits.setfRtsControl(WinBase.RTS_CONTROL_DISABLE); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(WinBase.RTS_CONTROL_DISABLE, lpDCB.controllBits.getfRtsControl()); - - - lpDCB.controllBits.setfAbortOnError(true); - assertEquals(16384, lpDCB.controllBits.longValue()); - assertEquals(true, lpDCB.controllBits.getfAbortOnError()); - lpDCB.controllBits.setfAbortOnError(false); - assertEquals(0, lpDCB.controllBits.longValue()); - assertEquals(false, lpDCB.controllBits.getfAbortOnError()); + //first we test if the WinBase.DCB bitfiled mapping works as expected. + WinBase.DCB lpDCB = new WinBase.DCB(); + lpDCB.controllBits.setValue(0); + + lpDCB.controllBits.setfBinary(true); + assertEquals(1, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfBinary()); + lpDCB.controllBits.setfBinary(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfBinary()); + + lpDCB.controllBits.setfParity(true); + assertEquals(2, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfParity()); + lpDCB.controllBits.setfParity(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfParity()); + + lpDCB.controllBits.setfOutxCtsFlow(true); + assertEquals(4, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfOutxCtsFlow()); + lpDCB.controllBits.setfOutxCtsFlow(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfOutxCtsFlow()); + + lpDCB.controllBits.setfOutxDsrFlow(true); + assertEquals(8, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfOutxDsrFlow()); + lpDCB.controllBits.setfOutxDsrFlow(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfOutxDsrFlow()); + + lpDCB.controllBits.setfDtrControl(WinBase.DTR_CONTROL_ENABLE); + assertEquals(16, lpDCB.controllBits.longValue()); + assertEquals(WinBase.DTR_CONTROL_ENABLE, lpDCB.controllBits.getfDtrControl()); + lpDCB.controllBits.setfDtrControl(WinBase.DTR_CONTROL_HANDSHAKE); + assertEquals(32, lpDCB.controllBits.longValue()); + assertEquals(WinBase.DTR_CONTROL_HANDSHAKE, lpDCB.controllBits.getfDtrControl()); + lpDCB.controllBits.setfDtrControl(WinBase.DTR_CONTROL_DISABLE); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(WinBase.DTR_CONTROL_DISABLE, lpDCB.controllBits.getfDtrControl()); + + lpDCB.controllBits.setfDsrSensitivity(true); + assertEquals(64, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfDsrSensitivity()); + lpDCB.controllBits.setfDsrSensitivity(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfDsrSensitivity()); + + lpDCB.controllBits.setfTXContinueOnXoff(true); + assertEquals(128, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfTXContinueOnXoff()); + lpDCB.controllBits.setfTXContinueOnXoff(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfTXContinueOnXoff()); + + lpDCB.controllBits.setfOutX(true); + assertEquals(256, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfOutX()); + lpDCB.controllBits.setfOutX(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfOutX()); + + lpDCB.controllBits.setfInX(true); + assertEquals(512, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfInX()); + lpDCB.controllBits.setfInX(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfInX()); + + lpDCB.controllBits.setfErrorChar(true); + assertEquals(1024, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfErrorChar()); + lpDCB.controllBits.setfErrorChar(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfErrorChar()); + + lpDCB.controllBits.setfNull(true); + assertEquals(2048, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfNull()); + lpDCB.controllBits.setfNull(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfNull()); + + + lpDCB.controllBits.setfRtsControl(WinBase.RTS_CONTROL_ENABLE); + assertEquals(4096, lpDCB.controllBits.longValue()); + assertEquals(WinBase.RTS_CONTROL_ENABLE, lpDCB.controllBits.getfRtsControl()); + lpDCB.controllBits.setfRtsControl(WinBase.RTS_CONTROL_HANDSHAKE); + assertEquals(8192, lpDCB.controllBits.longValue()); + assertEquals(WinBase.RTS_CONTROL_HANDSHAKE, lpDCB.controllBits.getfRtsControl()); + lpDCB.controllBits.setfRtsControl(WinBase.RTS_CONTROL_TOGGLE); + assertEquals(12288, lpDCB.controllBits.longValue()); + assertEquals(WinBase.RTS_CONTROL_TOGGLE, lpDCB.controllBits.getfRtsControl()); + lpDCB.controllBits.setfRtsControl(WinBase.RTS_CONTROL_DISABLE); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(WinBase.RTS_CONTROL_DISABLE, lpDCB.controllBits.getfRtsControl()); + + + lpDCB.controllBits.setfAbortOnError(true); + assertEquals(16384, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfAbortOnError()); + lpDCB.controllBits.setfAbortOnError(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfAbortOnError()); } public static void main(String[] args) { diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/WinDefTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/WinDefTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/WinDefTest.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/WinDefTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,44 @@ + +package com.sun.jna.platform.win32; + +import com.sun.jna.platform.win32.WinDef.DWORD; +import com.sun.jna.platform.win32.WinDef.WORD; +import org.junit.Test; +import static org.junit.Assert.*; + +public class WinDefTest { + + @Test + public void testWordExtractionFromDword() { + DWORD dword = new DWORD(0x12345678); + + assertEquals(new WORD(0x5678), dword.getLow()); + assertEquals(new WORD(0x1234), dword.getHigh()); + + DWORD dword2 = new DWORD(0xFFFFFFFF); + + assertEquals(new WORD(0xFFFF), dword2.getLow()); + assertEquals(new WORD(0xFFFF), dword2.getHigh()); + + DWORD dword3 = new DWORD(0x00000001); + + assertEquals(new WORD(0x0001), dword3.getLow()); + assertEquals(new WORD(0x0000), dword3.getHigh()); + + DWORD dword4 = new DWORD(0x00010000); + + assertEquals(new WORD(0x0000), dword4.getLow()); + assertEquals(new WORD(0x0001), dword4.getHigh()); + + DWORD dword5 = new DWORD(0x0000FFFF); + + assertEquals(new WORD(0xFFFF), dword5.getLow()); + assertEquals(new WORD(0x0000), dword5.getHigh()); + + DWORD dword6 = new DWORD(0xFFFF0000); + + assertEquals(new WORD(0x0000), dword6.getLow()); + assertEquals(new WORD(0xFFFF), dword6.getHigh()); + } + +} diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/WindowUtilsTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/WindowUtilsTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/WindowUtilsTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/WindowUtilsTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -26,6 +26,9 @@ import com.sun.jna.platform.win32.WinDef.DWORDByReference; import com.sun.jna.platform.win32.WinDef.HICON; import com.sun.jna.platform.win32.WinDef.HWND; +import com.sun.jna.platform.win32.WinDef.LPARAM; +import com.sun.jna.platform.win32.WinDef.LRESULT; +import com.sun.jna.platform.win32.WinDef.WPARAM; import com.sun.jna.platform.win32.WinUser; public class WindowUtilsTest extends TestCase { @@ -36,9 +39,10 @@ final List allVisibleWindows = WindowUtils .getAllWindows(true); - assertTrue(allWindows.size() > 0); - assertTrue(allVisibleWindows.size() > 0); - assertTrue(allWindows.size() > allVisibleWindows.size()); + assertTrue("Found no windows", allWindows.size() > 0); + assertTrue("Found no visible windows", allVisibleWindows.size() > 0); + assertTrue("Expected more non-visible windows than visible windows", + allWindows.size() > allVisibleWindows.size()); DesktopWindow explorerProc = null; for (final DesktopWindow dw : allWindows) { @@ -48,7 +52,8 @@ } } - assertNotNull(explorerProc); + assertNotNull("explorer.exe was not found among all windows", + explorerProc); explorerProc = null; for (final DesktopWindow dw : allVisibleWindows) { @@ -58,7 +63,8 @@ } } - assertNotNull(explorerProc); + assertNotNull("explorer.exe was not found among visible windows", + explorerProc); } public void testGetWindowIcon() throws Exception { @@ -70,8 +76,9 @@ "/res/test_icon.png").getPath()))); w.setIconImage(expectedIcon); w.setVisible(true); - HWND hwnd = new HWND(); - hwnd.setPointer(Native.getComponentPointer(w)); + Pointer p = Native.getComponentPointer(w); + assertNotNull("Couldn't obtain window HANDLE from JFrame", p); + HWND hwnd = new HWND(p); final BufferedImage obtainedIcon = WindowUtils.getWindowIcon(hwnd); @@ -149,15 +156,18 @@ .read(new FileInputStream(new File(getClass().getResource("/res/test_icon.png").getPath()))); w.setIconImage(expectedIcon); w.setVisible(true); - HWND hwnd = new HWND(); - hwnd.setPointer(Native.getComponentPointer(w)); + Pointer p = Native.getComponentPointer(w); + assertNotNull("Could not obtain native HANDLE for JFrame", p); + HWND hwnd = new HWND(p); final DWORDByReference hIconNumber = new DWORDByReference(); - long result = User32.INSTANCE.SendMessageTimeout(hwnd, - WinUser.WM_GETICON, WinUser.ICON_BIG, 0, - WinUser.SMTO_ABORTIFHUNG, 500, hIconNumber); + LRESULT result = User32.INSTANCE + .SendMessageTimeout(hwnd, WinUser.WM_GETICON, + new WPARAM(WinUser.ICON_BIG), + new LPARAM(0), + WinUser.SMTO_ABORTIFHUNG, 500, hIconNumber); - assertNotEquals(0, result); + assertNotEquals(0, result.intValue()); final HICON hIcon = new HICON(new Pointer(hIconNumber.getValue() .longValue())); diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/WininetTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/WininetTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/WininetTest.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/WininetTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,118 @@ +/* Copyright (c) 2015 Michael Freeman, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ +package com.sun.jna.platform.win32; + +import org.junit.Test; +import org.junit.runner.JUnitCore; + +import com.sun.jna.Native; +import com.sun.jna.platform.win32.WinNT.HANDLE; +import com.sun.jna.platform.win32.Wininet.INTERNET_CACHE_ENTRY_INFO; +import com.sun.jna.ptr.IntByReference; + +public class WininetTest extends AbstractWin32TestSupport { + + public static void main(String[] args) { + JUnitCore jUnitCore = new JUnitCore(); + jUnitCore.run(WininetTest.class); + } + + @Test + public void testFindCloseUrlCache() { + boolean result = Wininet.INSTANCE.FindCloseUrlCache(null); + int lastError = Native.getLastError(); + assertFalse("FindCloseUrlCache should return false with an invalid handle.", result); + assertEquals("GetLastError should return ERROR_INVALID_HANDLE", WinError.ERROR_INVALID_HANDLE, lastError); + } + + @Test + public void testDeleteUrlCacheEntry() { + boolean result = Wininet.INSTANCE.DeleteUrlCacheEntry("c:\\tempWinInetTest"); + int lastError = Native.getLastError(); + assertFalse("DeleteUrlCacheEntry should return false with a bogus path.", result); + assertEquals("GetLastError should return ERROR_FILE_NOT_FOUND", WinError.ERROR_FILE_NOT_FOUND, lastError); + } + + @Test + public void testFindFirstUrlCacheEntry() { + IntByReference size = new IntByReference(); + HANDLE cacheHandle = Wininet.INSTANCE.FindFirstUrlCacheEntry(null, null, size); + int lastError = Native.getLastError(); + // ERROR_INSUFFICIENT_BUFFER is returned when there are items in the cache + // ERROR_NO_MORE_ITEMS is returned when the cache is empty. + // Both are acceptable for a mapping test where the state of the cache would be unknown. + assertTrue("GetLastError should have returned ERROR_INSUFFICIENT_BUFFER or ERROR_NO_MORE_ITEMS.", lastError == WinError.ERROR_INSUFFICIENT_BUFFER || lastError == WinError.ERROR_NO_MORE_ITEMS); + assertNull("FindFirstUrlCacheEntry should have returned null.", cacheHandle); + } + + @Test + public void testFindNextUrlCacheEntry() { + HANDLE cacheHandle = null; + try { + IntByReference size = new IntByReference(); + int lastError = 0; + + // for every entry, we call the API twice: + // once to get the size into the IntByReference + // then again to get the actual item + cacheHandle = Wininet.INSTANCE.FindFirstUrlCacheEntry(null, null, size); + lastError = Native.getLastError(); + assertNull("FindFirstUrlCacheEntry should have returned null.", cacheHandle); + + // if the Wininet cache is empty, exercise FindNextUrlCacheEntry with an invalid handle + // just to ensure the mapping gets tested + if (lastError == WinError.ERROR_NO_MORE_ITEMS) { + boolean result = Wininet.INSTANCE.FindNextUrlCacheEntry(null, null, size); + lastError = Native.getLastError(); + assertFalse("FindNextUrlCacheEntry should have returned false.", result); + assertEquals("GetLastError should have returned ERROR_INVALID_PARAMETER.", + WinError.ERROR_INVALID_PARAMETER, lastError); + return; + } + + assertEquals("GetLastError should have returned ERROR_INSUFFICIENT_BUFFER.", + WinError.ERROR_INSUFFICIENT_BUFFER, lastError); + + INTERNET_CACHE_ENTRY_INFO entry = new INTERNET_CACHE_ENTRY_INFO(size.getValue()); + cacheHandle = Wininet.INSTANCE.FindFirstUrlCacheEntry(null, entry, size); + lastError = Native.getLastError(); + + assertNotNull("FindFirstUrlCacheEntry should not have returned null.", cacheHandle); + assertEquals("GetLastError should have returned ERROR_SUCCESS.", WinError.ERROR_SUCCESS, lastError); + + size = new IntByReference(); + + // for every entry, we call the API twice: + // once to get the size into the IntByReference + // then again to get the actual item + boolean result = Wininet.INSTANCE.FindNextUrlCacheEntry(cacheHandle, null, size); + lastError = Native.getLastError(); + assertFalse("FindNextUrlCacheEntry should have returned false.", result); + assertEquals("GetLastError should have returned ERROR_INSUFFICIENT_BUFFER.", + WinError.ERROR_INSUFFICIENT_BUFFER, lastError); + + entry = new INTERNET_CACHE_ENTRY_INFO(size.getValue()); + result = Wininet.INSTANCE.FindNextUrlCacheEntry(cacheHandle, entry, size); + lastError = Native.getLastError(); + assertTrue("FindNextUrlCacheEntry should have returned true.", result); + assertEquals("GetLastError should have returned ERROR_SUCCESS.", WinError.ERROR_SUCCESS, lastError); + + } finally { + if (cacheHandle != null) { + if (!Wininet.INSTANCE.FindCloseUrlCache(cacheHandle)) { + throw new Win32Exception(Native.getLastError()); + } + } + } + } +} diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/WininetUtilTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/WininetUtilTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/WininetUtilTest.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/WininetUtilTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,69 @@ +/* Copyright (c) 2015 Michael Freeman, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ +package com.sun.jna.platform.win32; + +import java.util.Map; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.JUnitCore; + +public class WininetUtilTest extends AbstractWin32TestSupport { + + public static void main(String[] args) { + JUnitCore jUnitCore = new JUnitCore(); + jUnitCore.run(WininetUtilTest.class); + } + + @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\""); + + // There's no easy way to monitor IE and see when it's done loading + // google.com, so just give it 10 seconds. + // Google keeps the homepage simple so 10 seconds should be enough time + // to get something into a cache. + Thread.sleep(10000); + } + + @Test + public void testGetCache() throws Exception { + + Map ieCache = WininetUtil.getCache(); + assertNotNull("WinInet cache should have some items in it.", ieCache.size() > 1); + + boolean historyEntryFound = false; + boolean googleLogoOrOtherImageFound = false; + for (String URL : ieCache.keySet()) { + if (URL.startsWith("Visited:") && URL.contains("www.google.com")) { + historyEntryFound = true; + } else if (URL.contains("google.com") && (URL.endsWith("png") || URL.endsWith("jpg"))) { + googleLogoOrOtherImageFound = true; + } + } + + assertTrue("Google logo (or other image) should have been found in the browser cache.", googleLogoOrOtherImageFound); + assertTrue("History entry for google.com should have been found in the browser cache.", historyEntryFound); + } + + @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*\""); + } +} diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/WinspoolTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/WinspoolTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/WinspoolTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/WinspoolTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -12,12 +12,15 @@ */ package com.sun.jna.platform.win32; -import junit.framework.TestCase; - +import com.sun.jna.Native; +import com.sun.jna.platform.win32.WinNT.HANDLEByReference; import com.sun.jna.platform.win32.Winspool.PRINTER_INFO_1; +import com.sun.jna.platform.win32.Winspool.PRINTER_INFO_2; import com.sun.jna.platform.win32.Winspool.PRINTER_INFO_4; import com.sun.jna.ptr.IntByReference; +import junit.framework.TestCase; + /** * @author dblock[at]dblock[dot]org */ @@ -30,40 +33,65 @@ public void testEnumPrinters_4() { IntByReference pcbNeeded = new IntByReference(); IntByReference pcReturned = new IntByReference(); - // if there're no printers installed, EnumPrinters will succeed with zero items returned - Winspool.INSTANCE.EnumPrinters(Winspool.PRINTER_ENUM_LOCAL, - null, 4, null, 0, pcbNeeded, pcReturned); + // if there are no printers installed, EnumPrinters will succeed with zero items returned + Winspool.INSTANCE.EnumPrinters(Winspool.PRINTER_ENUM_LOCAL, null, 4, null, 0, pcbNeeded, pcReturned); assertTrue(pcReturned.getValue() == 0); if (pcbNeeded.getValue() > 0) { - PRINTER_INFO_4 pPrinterEnum = new PRINTER_INFO_4(pcbNeeded.getValue()); - assertTrue(Winspool.INSTANCE.EnumPrinters(Winspool.PRINTER_ENUM_LOCAL, - null, 4, pPrinterEnum.getPointer(), pcbNeeded.getValue(), pcbNeeded, pcReturned)); - assertTrue(pcReturned.getValue() >= 0); + PRINTER_INFO_4 pPrinterEnum = new PRINTER_INFO_4(pcbNeeded.getValue()); + assertTrue(Winspool.INSTANCE.EnumPrinters(Winspool.PRINTER_ENUM_LOCAL, null, 4, pPrinterEnum.getPointer(), pcbNeeded.getValue(), pcbNeeded, pcReturned)); + assertTrue(pcReturned.getValue() >= 0); PRINTER_INFO_4[] printerInfo = (PRINTER_INFO_4[]) pPrinterEnum.toArray(pcReturned.getValue()); for(PRINTER_INFO_4 pi : printerInfo) { assertTrue(pi.pPrinterName == null || pi.pPrinterName.length() >= 0); - // System.out.println(pi.pPrinterName); } } } + public void testEnumPrinters_2() { + IntByReference pcbNeeded = new IntByReference(); + IntByReference pcReturned = new IntByReference(); + // if there are no printers installed, EnumPrinters will succeed with zero items returned + Winspool.INSTANCE.EnumPrinters(Winspool.PRINTER_ENUM_LOCAL, null, 2, null, 0, pcbNeeded, pcReturned); + assertTrue(pcReturned.getValue() == 0); + if (pcbNeeded.getValue() > 0) { + PRINTER_INFO_2 pPrinterEnum = new PRINTER_INFO_2(pcbNeeded.getValue()); + assertTrue(Winspool.INSTANCE.EnumPrinters(Winspool.PRINTER_ENUM_LOCAL, null, 2, pPrinterEnum.getPointer(), pcbNeeded.getValue(), pcbNeeded, pcReturned)); + assertTrue(pcReturned.getValue() >= 0); + PRINTER_INFO_2[] printerInfo = (PRINTER_INFO_2[]) pPrinterEnum.toArray(pcReturned.getValue()); + for(PRINTER_INFO_2 pi : printerInfo) { + assertTrue(pi.pPrinterName == null || pi.pPrinterName.length() >= 0); + } + } + } + public void testEnumPrinters_1() { IntByReference pcbNeeded = new IntByReference(); IntByReference pcReturned = new IntByReference(); - // if there're no printers installed, EnumPrinters will succeed with zero items returned - Winspool.INSTANCE.EnumPrinters(Winspool.PRINTER_ENUM_LOCAL, - null, 1, null, 0, pcbNeeded, pcReturned); + // if there are no printers installed, EnumPrinters will succeed with zero items returned + Winspool.INSTANCE.EnumPrinters(Winspool.PRINTER_ENUM_LOCAL, null, 1, null, 0, pcbNeeded, pcReturned); assertTrue(pcReturned.getValue() == 0); if (pcbNeeded.getValue() > 0) { PRINTER_INFO_1 pPrinterEnum = new PRINTER_INFO_1(pcbNeeded.getValue()); - assertTrue(Winspool.INSTANCE.EnumPrinters(Winspool.PRINTER_ENUM_LOCAL, - null, 1, pPrinterEnum.getPointer(), pcbNeeded.getValue(), pcbNeeded, pcReturned)); + assertTrue(Winspool.INSTANCE.EnumPrinters(Winspool.PRINTER_ENUM_LOCAL, null, 1, pPrinterEnum.getPointer(), pcbNeeded.getValue(), pcbNeeded, pcReturned)); assertTrue(pcReturned.getValue() >= 0); PRINTER_INFO_1[] printerInfo = (PRINTER_INFO_1[]) pPrinterEnum.toArray(pcReturned.getValue()); for(PRINTER_INFO_1 pi : printerInfo) { assertTrue(pi.pName == null || pi.pName.length() >= 0); - // System.out.println(pi.pName); } } } + + public void testOpenPrinter() { + HANDLEByReference hbr = new HANDLEByReference(); + boolean result = Winspool.INSTANCE.OpenPrinter("1234567890A123", hbr, null); + assertFalse("OpenPrinter should return false on failure.", result); + assertNull("The pointer-to-a-printer-handle should be null on failure.", hbr.getValue()); + assertEquals("GetLastError() should return ERROR_INVALID_PRINTER_NAME", WinError.ERROR_INVALID_PRINTER_NAME, Native.getLastError()); + } + + public void testClosePrinter() { + boolean result = Winspool.INSTANCE.ClosePrinter(null); + assertFalse("ClosePrinter should return false on failure.", result); + assertEquals("GetLastError() should return ERROR_INVALID_HANDLE", WinError.ERROR_INVALID_HANDLE, Native.getLastError()); + } } diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/WinspoolUtilTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/WinspoolUtilTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/WinspoolUtilTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/WinspoolUtilTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -23,7 +23,7 @@ public class WinspoolUtilTest extends TestCase { public static void main(String[] args) { - junit.textui.TestRunner.run(Shell32UtilTest.class); + junit.textui.TestRunner.run(WinspoolUtilTest.class); for(PRINTER_INFO_1 printerInfo : WinspoolUtil.getPrinterInfo1()) { System.out.println(printerInfo.pName + ": " + printerInfo.pDescription); } @@ -36,7 +36,21 @@ assertTrue(WinspoolUtil.getPrinterInfo1().length >= 0); } - public void testGetPrinterInfo4() { - assertTrue(WinspoolUtil.getPrinterInfo4().length >= 0); + public void testGetPrinterInfo2() { + assertTrue(WinspoolUtil.getPrinterInfo2().length >= 0); } + + public void testGetPrinterInfo2Specific() { + try { + WinspoolUtil.getPrinterInfo2("1234567890A123"); + fail("A Win32Exception with ERROR_INVALID_PRINTER_NAME should have been thrown instead of hitting this."); + } catch (Win32Exception e) { + assertEquals("A Win32Exception with ERROR_INVALID_PRINTER_NAME message should have been thrown.", + Kernel32Util.formatMessage(W32Errors.HRESULT_FROM_WIN32(WinError.ERROR_INVALID_PRINTER_NAME)), e.getMessage()); + } + } + + public void testGetPrinterInfo4() { + assertTrue(WinspoolUtil.getPrinterInfo4().length >= 0); + } } diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/Wtsapi32Test.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/Wtsapi32Test.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/Wtsapi32Test.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/Wtsapi32Test.java 2017-03-14 19:31:03.000000000 +0000 @@ -5,7 +5,6 @@ import com.sun.jna.Native; import junit.framework.TestCase; -import com.sun.jna.Pointer; import com.sun.jna.platform.win32.WinDef.HWND; public class Wtsapi32Test extends TestCase { diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/WTypesTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/WTypesTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/win32/WTypesTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/win32/WTypesTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -15,6 +15,7 @@ import com.sun.jna.Memory; import com.sun.jna.Native; import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.WTypes.BSTR; import junit.framework.TestCase; public class WTypesTest extends TestCase { @@ -53,7 +54,45 @@ WTypes.LPWSTR fromPointer = new WTypes.LPWSTR(TEST_POINTER); assertEquals(fromPointer.getValue(), TEST_STRING); } + + public void testBSTRBasic() { + String demoString = "input\u00D6\u00E4\u00DC?!"; + // Allocation via system and the "correct" way + BSTR sysAllocated = OleAuto.INSTANCE.SysAllocString(demoString); + // Java based allocation - not suitable if passed via automation + BSTR javaAllocated = new BSTR(demoString); + + // Ensure encoding roundtripping works + assertEquals(demoString, sysAllocated.getValue()); + assertEquals(demoString, javaAllocated.getValue()); + + // BSTR is encoded as UTF-16/UCS2, so byte length is 2 * char count + assertEquals(demoString.length(), OleAuto.INSTANCE.SysStringLen(sysAllocated)); + assertEquals(demoString.length(), OleAuto.INSTANCE.SysStringLen(javaAllocated)); + assertEquals(2 * demoString.length(), OleAuto.INSTANCE.SysStringByteLen(sysAllocated)); + assertEquals(2 * demoString.length(), OleAuto.INSTANCE.SysStringByteLen(javaAllocated)); + + // The BSTR Pointer points 4 bytes into the data itself (beginning of data + // string, the 4 preceding bytes code the string length (in bytes) + assertEquals(2 * demoString.length(), sysAllocated.getPointer().getInt(-4)); + assertEquals(2 * demoString.length(), javaAllocated.getPointer().getInt(-4)); + + OleAuto.INSTANCE.SysFreeString(sysAllocated); + // javaAllocated is allocated via Memory and will be freeed by the + // garbadge collector automaticly + } + public void testBSTRNullPointerHandling() { + // Allocation from NULL should return NULL + BSTR sysAllocated = OleAuto.INSTANCE.SysAllocString(null); + assertNull(sysAllocated); + + // MSDN states, that the BSTR from Nullpointer represents the string with + // zero characters + BSTR bstr = new BSTR(Pointer.NULL); + assertEquals("", bstr.getValue()); + } + public static void main(String[] args) { junit.textui.TestRunner.run(WTypesTest.class); } diff -Nru libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/WindowUtilsTest.java libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/WindowUtilsTest.java --- libjna-java-4.2.2/contrib/platform/test/com/sun/jna/platform/WindowUtilsTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/platform/test/com/sun/jna/platform/WindowUtilsTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -32,13 +32,8 @@ import java.awt.event.MouseEvent; import java.awt.geom.Area; import java.awt.image.BufferedImage; -import java.io.File; -import java.io.FileInputStream; import java.lang.ref.WeakReference; import java.util.Arrays; -import java.util.List; - -import javax.imageio.ImageIO; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JFrame; @@ -50,14 +45,7 @@ import junit.framework.TestCase; -import com.sun.jna.Native; import com.sun.jna.Platform; -import com.sun.jna.Pointer; -import com.sun.jna.platform.win32.User32; -import com.sun.jna.platform.win32.WinDef.DWORDByReference; -import com.sun.jna.platform.win32.WinDef.HICON; -import com.sun.jna.platform.win32.WinDef.HWND; -import com.sun.jna.platform.win32.WinUser; // NOTE: java.awt.Robot can't properly capture transparent pixels // Transparency tests are disabled until this can be resolved Binary files /tmp/tmptdXlQx/zXsTgf0UHo/libjna-java-4.2.2/contrib/platform/test/res/WevtapiTest.sample1.evtx and /tmp/tmptdXlQx/nhswvPAIcW/libjna-java-4.4.0/contrib/platform/test/res/WevtapiTest.sample1.evtx differ Binary files /tmp/tmptdXlQx/zXsTgf0UHo/libjna-java-4.2.2/contrib/platform/test/res/WevtapiTest.sample2.evtx and /tmp/tmptdXlQx/nhswvPAIcW/libjna-java-4.4.0/contrib/platform/test/res/WevtapiTest.sample2.evtx differ Binary files /tmp/tmptdXlQx/zXsTgf0UHo/libjna-java-4.2.2/contrib/platform/test/res/WevtapiTest.sample3.evtx and /tmp/tmptdXlQx/nhswvPAIcW/libjna-java-4.4.0/contrib/platform/test/res/WevtapiTest.sample3.evtx differ diff -Nru libjna-java-4.2.2/contrib/shapedwindowdemo/com/sun/jna/contrib/demo/ShapedWindowDemo.java libjna-java-4.4.0/contrib/shapedwindowdemo/com/sun/jna/contrib/demo/ShapedWindowDemo.java --- libjna-java-4.2.2/contrib/shapedwindowdemo/com/sun/jna/contrib/demo/ShapedWindowDemo.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/shapedwindowdemo/com/sun/jna/contrib/demo/ShapedWindowDemo.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,15 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.contrib.demo; diff -Nru libjna-java-4.2.2/contrib/w32keyhook/com/sun/jna/contrib/demo/KeyHook.java libjna-java-4.4.0/contrib/w32keyhook/com/sun/jna/contrib/demo/KeyHook.java --- libjna-java-4.2.2/contrib/w32keyhook/com/sun/jna/contrib/demo/KeyHook.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/w32keyhook/com/sun/jna/contrib/demo/KeyHook.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,15 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved - - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.contrib.demo; diff -Nru libjna-java-4.2.2/contrib/w32printing/build.xml libjna-java-4.4.0/contrib/w32printing/build.xml --- libjna-java-4.2.2/contrib/w32printing/build.xml 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/contrib/w32printing/build.xml 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,58 @@ + + + Builds, tests, and runs the project jnacontrib.w32printing. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru libjna-java-4.2.2/contrib/w32printing/src/com/sun/jna/platform/win32/Win32SpoolMonitor.java libjna-java-4.4.0/contrib/w32printing/src/com/sun/jna/platform/win32/Win32SpoolMonitor.java --- libjna-java-4.2.2/contrib/w32printing/src/com/sun/jna/platform/win32/Win32SpoolMonitor.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/w32printing/src/com/sun/jna/platform/win32/Win32SpoolMonitor.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,3 +1,25 @@ +/** + * 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 java.text.DateFormat; diff -Nru libjna-java-4.2.2/contrib/x11/src/jnacontrib/x11/api/X.java libjna-java-4.4.0/contrib/x11/src/jnacontrib/x11/api/X.java --- libjna-java-4.2.2/contrib/x11/src/jnacontrib/x11/api/X.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/x11/src/jnacontrib/x11/api/X.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2008 Stefan Endrullis, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

    - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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 jnacontrib.x11.api; @@ -455,7 +466,7 @@ for (int keyNr = 0; keyNr < count; keyNr++) { byte key = keys[modNr*count + keyNr]; if (key != 0) { - modifier.add(new Byte(key)); + modifier.add(Byte.valueOf(key)); } } } diff -Nru libjna-java-4.2.2/contrib/x11/src/jnacontrib/x11/demos/XDesktopDemo.java libjna-java-4.4.0/contrib/x11/src/jnacontrib/x11/demos/XDesktopDemo.java --- libjna-java-4.2.2/contrib/x11/src/jnacontrib/x11/demos/XDesktopDemo.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/x11/src/jnacontrib/x11/demos/XDesktopDemo.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2008 Stefan Endrullis, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

    - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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 jnacontrib.x11.demos; @@ -229,7 +240,7 @@ X.Window window = windows[i]; X.Window.Geometry geo = window.getGeometry(); int windowId = window.getID(); - data[i][0] = String.format("0x%08X", new Object[]{new Integer(windowId)}); + data[i][0] = String.format("0x%08X", new Object[]{Integer.valueOf(windowId)}); data[i][1] = "" + window.getDesktop(); data[i][2] = window.getTitle(); data[i][3] = "" + geo.x; diff -Nru libjna-java-4.2.2/contrib/x11/src/jnacontrib/x11/demos/XTestDemo.java libjna-java-4.4.0/contrib/x11/src/jnacontrib/x11/demos/XTestDemo.java --- libjna-java-4.2.2/contrib/x11/src/jnacontrib/x11/demos/XTestDemo.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/contrib/x11/src/jnacontrib/x11/demos/XTestDemo.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2008 Stefan Endrullis, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

    - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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 jnacontrib.x11.demos; diff -Nru libjna-java-4.2.2/debian/changelog libjna-java-4.4.0/debian/changelog --- libjna-java-4.2.2/debian/changelog 2017-04-12 08:52:44.000000000 +0000 +++ libjna-java-4.4.0/debian/changelog 2017-07-05 13:31:09.000000000 +0000 @@ -1,3 +1,16 @@ +libjna-java (4.4.0-1) unstable; urgency=medium + + * Team upload. + * New upstream release + - Refreshed the patches + - Added a link to ant.jar in the lib directory + * Install the javadoc under /usr/share/doc/libjna-java/api + * Include /usr/share/dpkg/pkg-info.mk instead of parsing dpkg-parsechangelog + * Standards-Version updated to 4.0.0 + * Switch to debhelper level 10 + + -- Emmanuel Bourg Wed, 05 Jul 2017 15:31:09 +0200 + libjna-java (4.2.2-3) unstable; urgency=medium * Team upload. diff -Nru libjna-java-4.2.2/debian/compat libjna-java-4.4.0/debian/compat --- libjna-java-4.2.2/debian/compat 2016-03-22 22:15:10.000000000 +0000 +++ libjna-java-4.4.0/debian/compat 2017-07-05 13:09:41.000000000 +0000 @@ -1 +1 @@ -9 +10 diff -Nru libjna-java-4.2.2/debian/control libjna-java-4.4.0/debian/control --- libjna-java-4.2.2/debian/control 2017-04-12 08:39:56.000000000 +0000 +++ libjna-java-4.4.0/debian/control 2017-07-05 13:09:41.000000000 +0000 @@ -7,7 +7,7 @@ Andrew Ross Build-Depends: ant, ant-optional, - debhelper (>= 9), + debhelper (>= 10), default-jdk, default-jdk-doc, javahelper (>=0.32~), @@ -16,7 +16,7 @@ libxt-dev, maven-repo-helper (>= 1.5~), pkg-config -Standards-Version: 3.9.8 +Standards-Version: 4.0.0 Vcs-Git: https://anonscm.debian.org/git/pkg-java/libjna-java.git Vcs-Browser: https://anonscm.debian.org/cgit/pkg-java/libjna-java.git Homepage: https://github.com/twall/jna diff -Nru libjna-java-4.2.2/debian/libjna-java-doc.doc-base libjna-java-4.4.0/debian/libjna-java-doc.doc-base --- libjna-java-4.2.2/debian/libjna-java-doc.doc-base 2016-03-22 22:15:10.000000000 +0000 +++ libjna-java-4.4.0/debian/libjna-java-doc.doc-base 2017-07-05 13:09:41.000000000 +0000 @@ -4,5 +4,5 @@ Section: Programming Format: HTML -Index: /usr/share/doc/libjna-java-doc/api/index.html -Files: /usr/share/doc/libjna-java-doc/api/*.html +Index: /usr/share/doc/libjna-java/api/index.html +Files: /usr/share/doc/libjna-java/api/*.html diff -Nru libjna-java-4.2.2/debian/libjna-java-doc.install libjna-java-4.4.0/debian/libjna-java-doc.install --- libjna-java-4.2.2/debian/libjna-java-doc.install 2016-03-22 22:15:10.000000000 +0000 +++ libjna-java-4.4.0/debian/libjna-java-doc.install 2017-07-05 13:09:41.000000000 +0000 @@ -1 +1 @@ -doc/javadoc/* /usr/share/doc/libjna-java-doc/api +doc/javadoc/* /usr/share/doc/libjna-java/api diff -Nru libjna-java-4.2.2/debian/patches/03-dynlink-and-cflags.patch libjna-java-4.4.0/debian/patches/03-dynlink-and-cflags.patch --- libjna-java-4.2.2/debian/patches/03-dynlink-and-cflags.patch 2016-03-22 22:15:10.000000000 +0000 +++ libjna-java-4.4.0/debian/patches/03-dynlink-and-cflags.patch 2017-07-05 13:09:51.000000000 +0000 @@ -3,7 +3,7 @@ --- a/build.xml +++ b/build.xml -@@ -827,6 +827,19 @@ +@@ -912,6 +912,19 @@ @@ -23,7 +23,7 @@ diff -Nru libjna-java-4.2.2/debian/patches/04-load-native-code-from-fs.patch libjna-java-4.4.0/debian/patches/04-load-native-code-from-fs.patch --- libjna-java-4.2.2/debian/patches/04-load-native-code-from-fs.patch 2016-03-22 22:15:10.000000000 +0000 +++ libjna-java-4.4.0/debian/patches/04-load-native-code-from-fs.patch 2017-07-05 13:09:52.000000000 +0000 @@ -3,7 +3,7 @@ Author: Jan Dittberner --- a/src/com/sun/jna/Native.java +++ b/src/com/sun/jna/Native.java -@@ -731,6 +731,30 @@ +@@ -828,6 +828,30 @@ } /** @@ -34,7 +34,7 @@ * Loads the JNA stub library. * First tries jna.boot.library.path, then the system path, then from the * jar file. -@@ -748,6 +772,9 @@ +@@ -844,6 +868,9 @@ String libName = System.getProperty("jna.boot.library.name", "jnidispatch"); String bootPath = System.getProperty("jna.boot.library.path"); diff -Nru libjna-java-4.2.2/debian/patches/06-remove-gjdoc-inexistent-options.patch libjna-java-4.4.0/debian/patches/06-remove-gjdoc-inexistent-options.patch --- libjna-java-4.2.2/debian/patches/06-remove-gjdoc-inexistent-options.patch 2016-03-22 22:15:10.000000000 +0000 +++ libjna-java-4.4.0/debian/patches/06-remove-gjdoc-inexistent-options.patch 2017-07-05 13:09:54.000000000 +0000 @@ -3,7 +3,7 @@ --- a/build.xml +++ b/build.xml -@@ -1105,7 +1105,7 @@ +@@ -1195,7 +1195,7 @@ diff -Nru libjna-java-4.2.2/debian/patches/09-javadoc.patch libjna-java-4.4.0/debian/patches/09-javadoc.patch --- libjna-java-4.2.2/debian/patches/09-javadoc.patch 2016-03-22 22:15:10.000000000 +0000 +++ libjna-java-4.4.0/debian/patches/09-javadoc.patch 2017-07-05 13:09:56.000000000 +0000 @@ -2,7 +2,7 @@ --- a/build.xml +++ b/build.xml -@@ -1088,7 +1088,7 @@ +@@ -1178,7 +1178,7 @@ JNA API Documentation

    ${header}
    ${footer} diff -Nru libjna-java-4.2.2/debian/patches/10-disable-full-jar.patch libjna-java-4.4.0/debian/patches/10-disable-full-jar.patch --- libjna-java-4.2.2/debian/patches/10-disable-full-jar.patch 2016-03-22 22:15:10.000000000 +0000 +++ libjna-java-4.4.0/debian/patches/10-disable-full-jar.patch 2017-07-05 13:09:58.000000000 +0000 @@ -3,7 +3,7 @@ Forwarded: not-needed --- a/build.xml +++ b/build.xml -@@ -379,6 +379,7 @@ +@@ -404,6 +404,7 @@ @@ -11,7 +11,7 @@ @@ -24,7 +24,7 @@ -@@ -510,6 +513,7 @@ +@@ -540,6 +543,7 @@ diff -Nru libjna-java-4.2.2/debian/patches/12-structure-backward-compatibility.patch libjna-java-4.4.0/debian/patches/12-structure-backward-compatibility.patch --- libjna-java-4.2.2/debian/patches/12-structure-backward-compatibility.patch 2016-03-22 22:15:10.000000000 +0000 +++ libjna-java-4.4.0/debian/patches/12-structure-backward-compatibility.patch 2017-07-05 13:09:41.000000000 +0000 @@ -5,7 +5,7 @@ Forwarded: not-needed --- a/src/com/sun/jna/Structure.java +++ b/src/com/sun/jna/Structure.java -@@ -106,6 +106,34 @@ +@@ -116,6 +116,34 @@ */ public interface ByReference { } @@ -40,12 +40,12 @@ /** Use the platform default alignment. */ public static final int ALIGN_DEFAULT = 0; /** No alignment, place all fields on nearest 1-byte boundary */ -@@ -874,7 +902,32 @@ +@@ -888,7 +916,32 @@ * guaranteed to be predictable. * @return ordered list of field names */ -- protected abstract List getFieldOrder(); -+ protected List getFieldOrder() { +- protected abstract List getFieldOrder(); ++ protected List getFieldOrder() { + if (REQUIRES_FIELD_ORDER) { + throw new Error("This VM does not store fields in a predictable order; you must implement Structure.getFieldOrder on " + getClass() + " to explicitly indicate the field order: " + System.getProperty("java.vendor") + ", " + System.getProperty("java.version")); + } diff -Nru libjna-java-4.2.2/debian/patches/13-reproducible-javadoc.patch libjna-java-4.4.0/debian/patches/13-reproducible-javadoc.patch --- libjna-java-4.2.2/debian/patches/13-reproducible-javadoc.patch 2016-03-22 22:15:10.000000000 +0000 +++ libjna-java-4.4.0/debian/patches/13-reproducible-javadoc.patch 2017-07-05 13:10:01.000000000 +0000 @@ -3,7 +3,7 @@ Forwarded: no --- a/build.xml +++ b/build.xml -@@ -1086,7 +1086,8 @@ +@@ -1176,7 +1176,8 @@ maxmemory="256m" packagenames="com.sun.jna,com.sun.jna.ptr,com.sun.jna.types,com.sun.jna.platform,com.sun.jna.platform.win32" overview="${src}/com/sun/jna/overview.html" diff -Nru libjna-java-4.2.2/debian/patches/14-rename-native-library.patch libjna-java-4.4.0/debian/patches/14-rename-native-library.patch --- libjna-java-4.2.2/debian/patches/14-rename-native-library.patch 2017-04-12 08:45:00.000000000 +0000 +++ libjna-java-4.4.0/debian/patches/14-rename-native-library.patch 2017-07-05 13:10:04.000000000 +0000 @@ -4,7 +4,7 @@ Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/libjna-java/+bug/1065253 --- a/src/com/sun/jna/Native.java +++ b/src/com/sun/jna/Native.java -@@ -770,8 +770,8 @@ +@@ -866,8 +866,8 @@ } } diff -Nru libjna-java-4.2.2/debian/rules libjna-java-4.4.0/debian/rules --- libjna-java-4.2.2/debian/rules 2017-04-12 08:39:56.000000000 +0000 +++ libjna-java-4.4.0/debian/rules 2017-07-05 13:29:32.000000000 +0000 @@ -1,12 +1,11 @@ #!/usr/bin/make -f +include /usr/share/dpkg/pkg-info.mk + export JAVA_HOME=/usr/lib/jvm/default-java DEB_HOST_MULTIARCH = $(shell dpkg-architecture -qDEB_HOST_MULTIARCH) -VERSION = $(shell dpkg-parsechangelog | sed -rne 's,^Version: ([^-]+).*,\1,p') -DATE = $(shell dpkg-parsechangelog --show-field Date) - %: dh $@ @@ -19,10 +18,12 @@ rm -rf contrib/platform/dist rm -Rf contrib/ntservice/dist rm -f dist/* + rm -f lib/*.jar mh_clean dh_clean override_dh_auto_build: + ln -s /usr/share/java/ant.jar lib/ant.jar ant -f build.xml \ -Dcflags_extra.native="" \ -Ddynlink.native=true \ @@ -31,16 +32,16 @@ -Djar.compress=true \ -Dmaven-release=true \ -Dbuild-native=true \ - -Dyear=$(shell date --date='$(DATE)' --utc +'%Y') \ + -Dyear=$(shell date --date='@$(SOURCE_DATE_EPOCH)' --utc +'%Y') \ jar javadoc contrib-jars native # install. using platform.jar is a silly idea in /usr/share/java/ as it's bound to collide override_dh_auto_install: - mh_installpom -plibjna-java -e$(VERSION) pom-jna.xml - mh_installjar -plibjna-java -e$(VERSION) --java-lib --usj-name=jna pom-jna.xml build/jna.jar + mh_installpom -plibjna-java -e$(DEB_VERSION_UPSTREAM) pom-jna.xml + mh_installjar -plibjna-java -e$(DEB_VERSION_UPSTREAM) --java-lib --usj-name=jna pom-jna.xml build/jna.jar - mh_installpom -plibjna-platform-java -e$(VERSION) pom-jna-platform.xml - mh_installjar -plibjna-platform-java -e$(VERSION) --java-lib --usj-name=jna-platform pom-jna-platform.xml contrib/platform/dist/jna-platform.jar + mh_installpom -plibjna-platform-java -e$(DEB_VERSION_UPSTREAM) pom-jna-platform.xml + mh_installjar -plibjna-platform-java -e$(DEB_VERSION_UPSTREAM) --java-lib --usj-name=jna-platform pom-jna-platform.xml contrib/platform/dist/jna-platform.jar dh_install -plibjna-jni build/native*/libjnidispatch.system.so usr/lib/$(DEB_HOST_MULTIARCH)/jni diff -Nru libjna-java-4.2.2/.github/ISSUE_TEMPLATE.md libjna-java-4.4.0/.github/ISSUE_TEMPLATE.md --- libjna-java-4.2.2/.github/ISSUE_TEMPLATE.md 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/.github/ISSUE_TEMPLATE.md 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,14 @@ +NOTE: Only file GitHub issues for bugs and feature requests. + +Before you post a new issue please check the +[JNA users' group](https://groups.google.com/forum/#!forum/jna-users) and the +existing issues for duplicates. Please use the user group also for general +questions. + +### Provide complete information about the problem +1. Version of JNA and related jars +2. Version and vendor of the java virtual machine +3. Operating system +4. System architecture (CPU type, bitness of the JVM) +5. Complete description of the problem +6. Steps to reproduce \ No newline at end of file diff -Nru libjna-java-4.2.2/LICENSE libjna-java-4.4.0/LICENSE --- libjna-java-4.2.2/LICENSE 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/LICENSE 2017-03-14 19:31:03.000000000 +0000 @@ -1,12 +1,9 @@ -JNA is dual-licensed under 2 alternative Open Source/Free -licenses: LGPL 2.1 and Apache License 2.0. (starting with -JNA version 4.0.0). - -What this means is that one can choose either one of these -licenses (for purposes of re-distributing JNA; usually by -including it as one of jars another application or -library uses) by downloading corresponding jar file, -using it, and living happily everafter. +Java Native Access project (JNA) 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: @@ -16,10 +13,10 @@ containing JNA, in file "LGPL2.1", under the same directory as this file. -You may obtain a copy of the ASL License at: +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 "ASL2.0", under the same directory +containing JNA, in file "AL2.0", under the same directory as this file. diff -Nru libjna-java-4.2.2/LICENSE.AL libjna-java-4.4.0/LICENSE.AL --- libjna-java-4.2.2/LICENSE.AL 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/LICENSE.AL 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,12 @@ +This copy of JNA is licensed under the +Apache (Software) License, version 2.0 ("the License"). +See the License for details about distribution rights, and the +specific rights regarding derivate works. + +You may obtain a copy of the License at: + +http://www.apache.org/licenses/ + +A copy is also included in the downloadable source code package +containing JNA, in file "AL2.0", under the same directory +as this file. diff -Nru libjna-java-4.2.2/LICENSE.ASL libjna-java-4.4.0/LICENSE.ASL --- libjna-java-4.2.2/LICENSE.ASL 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/LICENSE.ASL 1970-01-01 00:00:00.000000000 +0000 @@ -1,12 +0,0 @@ -This copy of JNA is licensed under the -Apache (Software) License, version 2.0 ("the License"). -See the License for details about distribution rights, and the -specific rights regarding derivate works. - -You may obtain a copy of the License at: - -http://www.apache.org/licenses/ - -A copy is also included in the downloadable source code package -containing JNA, in file "ASL2.0", under the same directory -as this file. diff -Nru libjna-java-4.2.2/native/build.xml libjna-java-4.4.0/native/build.xml --- libjna-java-4.2.2/native/build.xml 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/native/build.xml 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,385 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru libjna-java-4.2.2/native/callback.c libjna-java-4.4.0/native/callback.c --- libjna-java-4.2.2/native/callback.c 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/native/callback.c 2017-03-14 19:31:03.000000000 +0000 @@ -1,15 +1,26 @@ /* Copyright (c) 2007-2013 Timothy Wall, All Rights Reserved * Copyright (c) 2007 Wayne Meissner, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

    - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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". */ #include @@ -393,7 +404,7 @@ case CVT_NATIVE_MAPPED_WSTRING: // Make sure we have space enough for the new argument args[i+3] = alloca(sizeof(void *)); - *((void **)args[i+3]) = fromNative(env, cb->arg_classes[i], cif->arg_types[i], cbargs[i], JNI_FALSE, cb->encoding); + *((void **)args[i+3]) = fromNativeCallbackParam(env, cb->arg_classes[i], cif->arg_types[i], cbargs[i], JNI_FALSE, cb->encoding); break; case CVT_POINTER: *((void **)args[i+3]) = newJavaPointer(env, *(void **)cbargs[i]); @@ -682,7 +693,7 @@ tls->jvm_thread = JNI_FALSE; } // Dispose of allocated memory - free(args.name); + free((void *)args.name); if (attach_status != JNI_OK) { fprintf(stderr, "JNA: Can't attach native thread to VM for callback: %d\n", attach_status); return; diff -Nru libjna-java-4.2.2/native/dispatch.c libjna-java-4.4.0/native/dispatch.c --- libjna-java-4.2.2/native/dispatch.c 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/native/dispatch.c 2017-03-14 19:31:03.000000000 +0000 @@ -5,17 +5,32 @@ * Copyright (c) 2007-2013 Timothy Wall. All Rights Reserved. * Copyright (c) 2007 Wayne Meissner. All Rights Reserved. * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

    - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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". */ +#include "dispatch.h" + +#include + #if defined(_WIN32) #define WIN32_LEAN_AND_MEAN #include @@ -45,6 +60,7 @@ #else #include #include +#include #define STRTYPE char* #ifdef USE_DEFAULT_LIBNAME_ENCODING #define NAME2CSTR(ENV,JSTR) newCString(ENV,JSTR) @@ -53,8 +69,21 @@ #endif #define DEFAULT_LOAD_OPTS (RTLD_LAZY|RTLD_GLOBAL) #define LOAD_LIBRARY(NAME,OPTS) dlopen(NAME, OPTS) -#define LOAD_ERROR(BUF,LEN) (snprintf(BUF, LEN, "%s", dlerror()), BUF) -#define STR_ERROR(CODE,BUF,LEN) (strerror_r(CODE, BUF, LEN), BUF) +static inline char * LOAD_ERROR(char * buf, size_t len) { + const size_t count = snprintf(buf, len, "%s", dlerror()); + assert(count <= len && "snprintf() output has been truncated"); + return buf; +} +static inline char * STR_ERROR(int code, char * buf, size_t len) { + // The conversion will fail if code is not a valid error code. + int err = strerror_r(code, buf, len); + if (err) + // Depending on glib version, "Unknown error" error code + // may be returned or passed using errno. + err = strerror_r(err > 0 ? err : errno, buf, len); + assert(err == 0 && "strerror_r() conversion has failed"); + return buf; +} #define FREE_LIBRARY(HANDLE) dlclose(HANDLE) #define FIND_ENTRY(HANDLE, NAME) dlsym(HANDLE, NAME) #endif @@ -67,16 +96,9 @@ #endif #include -// Force XSI-compliant strerror_r (http://unixhelp.ed.ac.uk/CGI/man-cgi?strerror) -#ifndef _XOPEN_SOURCE -#define _XOPEN_SOURCE 600 -#endif -#include #include #include -#include "dispatch.h" - #ifndef NO_JAWT #include #include @@ -97,6 +119,8 @@ #ifdef __cplusplus extern "C" { +#else +#include #endif #define MEMCPY(ENV,D,S,L) do { \ @@ -108,6 +132,7 @@ #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 /* Cached class, field and method IDs */ static jclass classObject; @@ -183,6 +208,7 @@ static jmethodID MID_Pointer_init; static jmethodID MID_Native_dispose; +static jmethodID MID_Native_fromNativeCallbackParam; static jmethodID MID_Native_fromNative; static jmethodID MID_Native_nativeType; static jmethodID MID_Native_toNativeTypeMapped; @@ -268,11 +294,8 @@ size_t size = wcslen(wstr) + 5; wchar_t* prefixed = (wchar_t*)alloca(sizeof(wchar_t) * size); -#ifdef _MSC_VER swprintf(prefixed, size, L"\\\\?\\%ls", wstr); -#else - swprintf(prefixed, L"\\\\?\\%ls", wstr); -#endif + if ((required = GetShortPathNameW(prefixed, NULL, 0)) != 0) { wchar_t* wshort = (wchar_t*)malloc(sizeof(wchar_t) * required); if (GetShortPathNameW(prefixed, wshort, required)) { @@ -435,6 +458,7 @@ 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; nargs = (*env)->GetArrayLength(env, args); @@ -609,7 +633,9 @@ break; } - status = ffi_prep_cif(&cif, abi, nargs, return_type, arg_types); + status = fixed_args + ? ffi_prep_cif_var(&cif, abi, fixed_args, nargs, return_type, arg_types) + : ffi_prep_cif(&cif, abi, nargs, return_type, arg_types); if (!ffi_error(env, "Native call setup", status)) { PSTART(); if ((flags & THROW_LAST_ERROR) != 0) { @@ -1091,7 +1117,7 @@ if (args->name != NULL) { // Make a copy, since the Java Structure which owns this native memory // will go out of scope and be available for GC - args->name = strdup(args->name); + args->name = STRDUP(args->name); } } } @@ -1147,16 +1173,17 @@ fromNativeTypeMapped(JNIEnv* env, jobject from_native, void* native_return_value, int jtype, size_t size, - jclass java_return_class, + jobject java_method, void* result_storage, const char* encoding) { jobject value = new_object(env, (char)jtype, native_return_value, JNI_TRUE, encoding); if (!(*env)->ExceptionCheck(env)) { jobject obj = (*env)->CallStaticObjectMethod(env, classNative, MID_Native_fromNativeTypeMapped, - from_native, value, java_return_class); + from_native, value, java_method); if (!(*env)->ExceptionCheck(env)) { // Convert objects into primitive types if the return class demands it + jclass java_return_class = (*env)->CallObjectMethod(env, java_method, MID_Method_getReturnType); if ((*env)->IsSameObject(env, java_return_class, classPrimitiveBoolean) || (*env)->IsSameObject(env, java_return_class, classPrimitiveByte) || (*env)->IsSameObject(env, java_return_class, classPrimitiveCharacter) @@ -1175,17 +1202,29 @@ } jobject -fromNative(JNIEnv* env, jclass javaClass, ffi_type* type, void* resp, jboolean promote, const char* encoding) { +fromNativeCallbackParam(JNIEnv* env, jclass javaClass, ffi_type* type, void* resp, jboolean promote, const char* encoding) { int jtype = get_java_type_from_ffi_type(type); jobject value = new_object(env, (char)jtype, resp, promote, encoding); if (!(*env)->ExceptionCheck(env)) { return (*env)->CallStaticObjectMethod(env, classNative, - MID_Native_fromNative, + MID_Native_fromNativeCallbackParam, javaClass, value); } return NULL; } +jobject +fromNative(JNIEnv* env, jobject javaMethod, ffi_type* type, void* resp, jboolean promote, const char* encoding) { + int jtype = get_java_type_from_ffi_type(type); + jobject value = new_object(env, (char)jtype, resp, promote, encoding); + if (!(*env)->ExceptionCheck(env)) { + return (*env)->CallStaticObjectMethod(env, classNative, + MID_Native_fromNative, + javaMethod, value); + } + return NULL; +} + static ffi_type* getStructureType(JNIEnv *env, jobject obj) { @@ -1670,7 +1709,7 @@ ffi_type** closure_arg_types; int* flags; int rflag; - jclass closure_rclass; + jobject closure_method; jobject* to_native; jobject from_native; jboolean throw_last_error; @@ -1860,7 +1899,7 @@ ? 'c' : (data->rflag == CVT_TYPE_MAPPER_WSTRING ? 'w' : get_java_type_from_ffi_type(data->cif.rtype))); fromNativeTypeMapped(env, data->from_native, resp, jtype, data->cif.rtype->size, - data->closure_rclass, oldresp, data->encoding); + data->closure_method, oldresp, data->encoding); } break; case CVT_INTEGER_TYPE: @@ -1868,7 +1907,7 @@ case CVT_NATIVE_MAPPED: case CVT_NATIVE_MAPPED_STRING: case CVT_NATIVE_MAPPED_WSTRING: - *(void **)oldresp = fromNative(env, data->closure_rclass, data->cif.rtype, resp, JNI_TRUE, data->encoding); + *(void **)oldresp = fromNative(env, data->closure_method, data->cif.rtype, resp, JNI_TRUE, data->encoding); break; case CVT_POINTER: *(void **)resp = newJavaPointer(env, *(void **)resp); @@ -1880,13 +1919,22 @@ *(void **)resp = newJavaWString(env, *(void **)resp); break; case CVT_STRUCTURE: - *(void **)resp = newJavaStructure(env, *(void **)resp, data->closure_rclass); + { + jclass return_class = (*env)->CallObjectMethod(env, data->closure_method, MID_Method_getReturnType); + *(void **)resp = newJavaStructure(env, *(void **)resp, return_class); + } break; case CVT_STRUCTURE_BYVAL: - *(void **)oldresp = newJavaStructure(env, resp, data->closure_rclass); + { + jclass return_class = (*env)->CallObjectMethod(env, data->closure_method, MID_Method_getReturnType); + *(void **)oldresp = newJavaStructure(env, resp, return_class); + } break; case CVT_CALLBACK: - *(void **)resp = newJavaCallback(env, *(void **)resp, data->closure_rclass); + { + jclass return_class = (*env)->CallObjectMethod(env, data->closure_method, MID_Method_getReturnType); + *(void **)resp = newJavaCallback(env, *(void **)resp, return_class); + } break; default: break; @@ -1979,13 +2027,14 @@ //////////////////// /* - * Class: Native + * Class: com_sun_jna_Native * Method: invokePointer - * Signature: (JI[Ljava/lang/Object;)J; + * Signature: (Lcom/sun/jna/Function;JI[Ljava/lang/Object;)J */ -JNIEXPORT jlong JNICALL -Java_com_sun_jna_Native_invokePointer(JNIEnv *env, jclass UNUSED(cls), - jlong fp, jint callconv, jobjectArray arr) +JNIEXPORT jlong JNICALL +Java_com_sun_jna_Native_invokePointer (JNIEnv *env, jclass UNUSED(cls), + jobject UNUSED(function), jlong fp, + jint callconv, jobjectArray arr) { jvalue result; dispatch(env, L2A(fp), callconv, arr, &ffi_type_pointer, &result); @@ -1994,13 +2043,14 @@ /* - * Class: Native + * Class: com_sun_jna_Native * Method: invokeObject - * Signature: (JI[Ljava/lang/Object;)Ljava/lang/Object; + * Signature: (Lcom/sun/jna/Function;JI[Ljava/lang/Object;)Ljava/lang/Object; */ -JNIEXPORT jobject JNICALL -Java_com_sun_jna_Native_invokeObject(JNIEnv *env, jclass UNUSED(cls), - jlong fp, jint callconv, jobjectArray arr) +JNIEXPORT jobject +JNICALL Java_com_sun_jna_Native_invokeObject(JNIEnv *env, jclass UNUSED(cls), + jobject UNUSED(function), jlong fp, + jint callconv, jobjectArray arr) { jvalue result; dispatch(env, L2A(fp), callconv, arr, &ffi_type_pointer, &result); @@ -2009,13 +2059,14 @@ /* - * Class: Native + * Class: com_sun_jna_Native * Method: invokeStructure - * Signature: (JI[Ljava/lang/Object;Lcom/sun/jna/Structure)LStructure; + * Signature: (Lcom/sun/jna/Function;JI[Ljava/lang/Object;JJ)V */ -JNIEXPORT void JNICALL -Java_com_sun_jna_Native_invokeStructure(JNIEnv *env, jclass UNUSED(cls), - jlong fp, jint callconv, jobjectArray arr, +JNIEXPORT void JNICALL +Java_com_sun_jna_Native_invokeStructure(JNIEnv *env, jclass UNUSED(cls), + jobject UNUSED(function), jlong fp, + jint callconv, jobjectArray arr, jlong memory, jlong type_info) { ffi_type* rtype = (ffi_type*)L2A(type_info); @@ -2028,13 +2079,14 @@ } /* - * Class: Native + * Class: com_sun_jna_Native * Method: invokeDouble - * Signature: (JI[Ljava/lang/Object;)D + * Signature: (Lcom/sun/jna/Function;JI[Ljava/lang/Object;)D */ JNIEXPORT jdouble JNICALL -Java_com_sun_jna_Native_invokeDouble(JNIEnv *env, jclass UNUSED(cls), - jlong fp, jint callconv, jobjectArray arr) +Java_com_sun_jna_Native_invokeDouble(JNIEnv *env, jclass UNUSED(cls), + jobject UNUSED(function), jlong fp, + jint callconv, jobjectArray arr) { jvalue result; dispatch(env, L2A(fp), callconv, arr, &ffi_type_double, &result); @@ -2042,13 +2094,14 @@ } /* - * Class: Native + * Class: com_sun_jna_Native * Method: invokeFloat - * Signature: (JI[Ljava/lang/Object;)F + * Signature: (Lcom/sun/jna/Function;JI[Ljava/lang/Object;)F */ JNIEXPORT jfloat JNICALL -Java_com_sun_jna_Native_invokeFloat(JNIEnv *env, jclass UNUSED(cls), - jlong fp, jint callconv, jobjectArray arr) +Java_com_sun_jna_Native_invokeFloat(JNIEnv *env, jclass UNUSED(cls), + jobject UNUSED(function), jlong fp, + jint callconv, jobjectArray arr) { jvalue result; dispatch(env, L2A(fp), callconv, arr, &ffi_type_float, &result); @@ -2056,13 +2109,14 @@ } /* - * Class: Native + * Class: com_sun_jna_Native * Method: invokeInt - * Signature: (JI[Ljava/lang/Object;)I + * Signature: (Lcom/sun/jna/Function;JI[Ljava/lang/Object;)I */ JNIEXPORT jint JNICALL -Java_com_sun_jna_Native_invokeInt(JNIEnv *env, jclass UNUSED(cls), - jlong fp, jint callconv, jobjectArray arr) +Java_com_sun_jna_Native_invokeInt(JNIEnv *env, jclass UNUSED(cls), + jobject UNUSED(function), jlong fp, jint callconv, + jobjectArray arr) { ffi_arg result; dispatch(env, L2A(fp), callconv, arr, &ffi_type_sint32, &result); @@ -2070,13 +2124,14 @@ } /* - * Class: Native + * Class: com_sun_jna_Native * Method: invokeLong - * Signature: (JI[Ljava/lang/Object;)J + * Signature: (Lcom/sun/jna/Function;JI[Ljava/lang/Object;)J */ JNIEXPORT jlong JNICALL Java_com_sun_jna_Native_invokeLong(JNIEnv *env, jclass UNUSED(cls), - jlong fp, jint callconv, jobjectArray arr) + jobject UNUSED(function), jlong fp, jint callconv, + jobjectArray arr) { jvalue result; dispatch(env, L2A(fp), callconv, arr, &ffi_type_sint64, &result); @@ -2084,13 +2139,14 @@ } /* - * Class: Native + * Class: com_sun_jna_Native * Method: invokeVoid - * Signature: (JI[Ljava/lang/Object;)V + * Signature: (Lcom/sun/jna/Function;JI[Ljava/lang/Object;)V */ JNIEXPORT void JNICALL Java_com_sun_jna_Native_invokeVoid(JNIEnv *env, jclass UNUSED(cls), - jlong fp, jint callconv, jobjectArray arr) + jobject UNUSED(function), jlong fp, jint callconv, + jobjectArray arr) { jvalue result; dispatch(env, L2A(fp), callconv, arr, &ffi_type_void, &result); @@ -2202,103 +2258,103 @@ } /* - * Class: Native - * Method: _write - * Signature: (J[BII)V + * Class: com_sun_jna_Native + * Method: write + * Signature: (Lcom/sun/jna/Pointer;JJ[BII)V */ -JNIEXPORT void JNICALL Java_com_sun_jna_Native_write__J_3BII -(JNIEnv *env, jclass UNUSED(cls), jlong addr, jbyteArray arr, jint off, jint n) +JNIEXPORT void JNICALL Java_com_sun_jna_Native_write__Lcom_sun_jna_Pointer_2JJ_3BII +(JNIEnv *env, jclass UNUSED(cls), jobject UNUSED(pointer), jlong addr, jlong offset, jbyteArray arr, jint off, jint n) { PSTART(); - (*env)->GetByteArrayRegion(env, arr, off, n, L2A(addr)); + (*env)->GetByteArrayRegion(env, arr, off, n, L2A(addr + offset)); PEND(env); } /* - * Class: Native - * Method: _write - * Signature: (J[CII)V + * Class: com_sun_jna_Native + * Method: write + * Signature: (Lcom/sun/jna/Pointer;JJ[CII)V */ -JNIEXPORT void JNICALL Java_com_sun_jna_Native_write__J_3CII -(JNIEnv *env, jclass UNUSED(cls), jlong addr, jcharArray arr, jint off, jint n) +JNIEXPORT void JNICALL Java_com_sun_jna_Native_write__Lcom_sun_jna_Pointer_2JJ_3CII +(JNIEnv *env, jclass UNUSED(cls), jobject UNUSED(pointer), jlong addr, jlong offset, jcharArray arr, jint off, jint n) { - getChars(env, (wchar_t*)L2A(addr), arr, off, n); + getChars(env, (wchar_t*)L2A(addr + offset), arr, off, n); } /* - * Class: Native - * Method: _write - * Signature: (J[DII)V + * Class: com_sun_jna_Native + * Method: write + * Signature: (Lcom/sun/jna/Pointer;JJ[DII)V */ -JNIEXPORT void JNICALL Java_com_sun_jna_Native_write__J_3DII -(JNIEnv *env, jclass UNUSED(cls), jlong addr, jdoubleArray arr, jint off, jint n) +JNIEXPORT void JNICALL Java_com_sun_jna_Native_write__Lcom_sun_jna_Pointer_2JJ_3DII +(JNIEnv *env, jclass UNUSED(cls), jobject UNUSED(pointer), jlong addr, jlong offset, jdoubleArray arr, jint off, jint n) { PSTART(); - (*env)->GetDoubleArrayRegion(env, arr, off, n, (jdouble*)L2A(addr)); + (*env)->GetDoubleArrayRegion(env, arr, off, n, (jdouble*)L2A(addr + offset)); PEND(env); } /* - * Class: Native - * Method: _write - * Signature: (J[FII)V + * Class: com_sun_jna_Native + * Method: write + * Signature: (Lcom/sun/jna/Pointer;JJ[FII)V */ -JNIEXPORT void JNICALL Java_com_sun_jna_Native_write__J_3FII -(JNIEnv *env, jclass UNUSED(cls), jlong addr, jfloatArray arr, jint off, jint n) +JNIEXPORT void JNICALL Java_com_sun_jna_Native_write__Lcom_sun_jna_Pointer_2JJ_3FII +(JNIEnv *env, jclass UNUSED(cls), jobject UNUSED(pointer), jlong addr, jlong offset, jfloatArray arr, jint off, jint n) { PSTART(); - (*env)->GetFloatArrayRegion(env, arr, off, n, (jfloat*)L2A(addr)); + (*env)->GetFloatArrayRegion(env, arr, off, n, (jfloat*)L2A(addr + offset)); PEND(env); } /* - * Class: Native - * Method: _write - * Signature: (J[III)V + * Class: com_sun_jna_Native + * Method: write + * Signature: (Lcom/sun/jna/Pointer;JJ[III)V */ -JNIEXPORT void JNICALL Java_com_sun_jna_Native_write__J_3III -(JNIEnv *env, jclass UNUSED(cls), jlong addr, jintArray arr, jint off, jint n) +JNIEXPORT void JNICALL Java_com_sun_jna_Native_write__Lcom_sun_jna_Pointer_2JJ_3III +(JNIEnv *env, jclass UNUSED(cls), jobject UNUSED(pointer), jlong addr, jlong offset, jintArray arr, jint off, jint n) { PSTART(); - (*env)->GetIntArrayRegion(env, arr, off, n, (jint*)L2A(addr)); + (*env)->GetIntArrayRegion(env, arr, off, n, (jint*)L2A(addr + offset)); PEND(env); } /* - * Class: Native - * Method: _write - * Signature: (J[JII)V + * Class: com_sun_jna_Native + * Method: write + * Signature: (Lcom/sun/jna/Pointer;JJ[JII)V */ -JNIEXPORT void JNICALL Java_com_sun_jna_Native_write__J_3JII -(JNIEnv *env, jclass UNUSED(cls), jlong addr, jlongArray arr, jint off, jint n) +JNIEXPORT void JNICALL Java_com_sun_jna_Native_write__Lcom_sun_jna_Pointer_2JJ_3JII +(JNIEnv *env, jclass UNUSED(cls), jobject UNUSED(pointer), jlong addr, jlong offset, jlongArray arr, jint off, jint n) { PSTART(); - (*env)->GetLongArrayRegion(env, arr, off, n, (jlong*)L2A(addr)); + (*env)->GetLongArrayRegion(env, arr, off, n, (jlong*)L2A(addr + offset)); PEND(env); } /* - * Class: Native - * Method: _write - * Signature: (J[SII)V + * Class: com_sun_jna_Native + * Method: write + * Signature: (Lcom/sun/jna/Pointer;JJ[SII)V */ -JNIEXPORT void JNICALL Java_com_sun_jna_Native_write__J_3SII -(JNIEnv *env, jclass UNUSED(cls), jlong addr, jshortArray arr, jint off, jint n) +JNIEXPORT void JNICALL Java_com_sun_jna_Native_write__Lcom_sun_jna_Pointer_2JJ_3SII +(JNIEnv *env, jclass UNUSED(cls), jobject UNUSED(pointer), jlong addr, jlong offset, jshortArray arr, jint off, jint n) { PSTART(); - (*env)->GetShortArrayRegion(env, arr, off, n, (jshort*)L2A(addr)); + (*env)->GetShortArrayRegion(env, arr, off, n, (jshort*)L2A(addr + offset)); PEND(env); } /* - * Class: Native - * Method: _indexOf - * Signature: (JB)J + * Class: com_sun_jna_Native + * Method: indexOf + * Signature: (Lcom/sun/jna/Pointer;JJB)J */ -JNIEXPORT jlong JNICALL Java_com_sun_jna_Native_indexOf__JB -(JNIEnv * UNUSED_ENV(env), jclass UNUSED(cls), jlong addr, jbyte value) +JNIEXPORT jlong JNICALL Java_com_sun_jna_Native_indexOf +(JNIEnv * UNUSED_ENV(env), jclass UNUSED(cls), jobject UNUSED(pointer), jlong addr, jlong offset, jbyte value) { - jbyte *peer = (jbyte *)L2A(addr); + jbyte *peer = (jbyte *)L2A(addr + offset); volatile jlong i = 0; volatile jlong result = -1L; PSTART(); @@ -2313,124 +2369,124 @@ } /* - * Class: Native - * Method: _read - * Signature: (J[BII)V + * Class: com_sun_jna_Native + * Method: read + * Signature: (Lcom/sun/jna/Pointer;JJ[BII)V */ -JNIEXPORT void JNICALL Java_com_sun_jna_Native_read__J_3BII -(JNIEnv *env, jclass UNUSED(cls), jlong addr, jbyteArray arr, jint off, jint n) +JNIEXPORT void JNICALL Java_com_sun_jna_Native_read__Lcom_sun_jna_Pointer_2JJ_3BII +(JNIEnv *env, jclass UNUSED(cls), jobject UNUSED(pointer), jlong addr, jlong offset, jbyteArray arr, jint off, jint n) { PSTART(); - (*env)->SetByteArrayRegion(env, arr, off, n, L2A(addr)); + (*env)->SetByteArrayRegion(env, arr, off, n, L2A(addr + offset)); PEND(env); } /* - * Class: Native - * Method: _read - * Signature: (J[CII)V + * Class: com_sun_jna_Native + * Method: read + * Signature: (Lcom/sun/jna/Pointer;JJ[CII)V */ -JNIEXPORT void JNICALL Java_com_sun_jna_Native_read__J_3CII - (JNIEnv *env, jclass UNUSED(cls), jlong addr, jcharArray arr, jint off, jint n) +JNIEXPORT void JNICALL Java_com_sun_jna_Native_read__Lcom_sun_jna_Pointer_2JJ_3CII + (JNIEnv *env, jclass UNUSED(cls), jobject UNUSED(pointer), jlong addr, jlong offset, jcharArray arr, jint off, jint n) { - setChars(env, (wchar_t*)L2A(addr), arr, off, n); + setChars(env, (wchar_t*)L2A(addr + offset), arr, off, n); } /* - * Class: Native - * Method: _read - * Signature: (J[DII)V + * Class: com_sun_jna_Native + * Method: read + * Signature: (Lcom/sun/jna/Pointer;JJ[DII)V */ -JNIEXPORT void JNICALL Java_com_sun_jna_Native_read__J_3DII - (JNIEnv *env, jclass UNUSED(cls), jlong addr, jdoubleArray arr, jint off, jint n) +JNIEXPORT void JNICALL Java_com_sun_jna_Native_read__Lcom_sun_jna_Pointer_2JJ_3DII + (JNIEnv *env, jclass UNUSED(cls), jobject UNUSED(pointer), jlong addr, jlong offset, jdoubleArray arr, jint off, jint n) { PSTART(); - (*env)->SetDoubleArrayRegion(env, arr, off, n, (jdouble*)L2A(addr)); + (*env)->SetDoubleArrayRegion(env, arr, off, n, (jdouble*)L2A(addr + offset)); PEND(env); } /* - * Class: Native - * Method: _read - * Signature: (J[FII)V + * Class: com_sun_jna_Native + * Method: read + * Signature: (Lcom/sun/jna/Pointer;JJ[FII)V */ -JNIEXPORT void JNICALL Java_com_sun_jna_Native_read__J_3FII - (JNIEnv *env, jclass UNUSED(cls), jlong addr, jfloatArray arr, jint off, jint n) +JNIEXPORT void JNICALL Java_com_sun_jna_Native_read__Lcom_sun_jna_Pointer_2JJ_3FII + (JNIEnv *env, jclass UNUSED(cls), jobject UNUSED(pointer), jlong addr, jlong offset, jfloatArray arr, jint off, jint n) { PSTART(); - (*env)->SetFloatArrayRegion(env, arr, off, n, (jfloat*)L2A(addr)); + (*env)->SetFloatArrayRegion(env, arr, off, n, (jfloat*)L2A(addr + offset)); PEND(env); } /* - * Class: Native - * Method: _read - * Signature: (J[III)V + * Class: com_sun_jna_Native + * Method: read + * Signature: (Lcom/sun/jna/Pointer;JJ[III)V */ -JNIEXPORT void JNICALL Java_com_sun_jna_Native_read__J_3III - (JNIEnv *env, jclass UNUSED(cls), jlong addr, jintArray arr, jint off, jint n) +JNIEXPORT void JNICALL Java_com_sun_jna_Native_read__Lcom_sun_jna_Pointer_2JJ_3III + (JNIEnv *env, jclass UNUSED(cls), jobject UNUSED(pointer), jlong addr, jlong offset, jintArray arr, jint off, jint n) { PSTART(); - (*env)->SetIntArrayRegion(env, arr, off, n, (jint*)L2A(addr)); + (*env)->SetIntArrayRegion(env, arr, off, n, (jint*)L2A(addr + offset)); PEND(env); } /* - * Class: Native - * Method: _read - * Signature: (J[JII)V + * Class: com_sun_jna_Native + * Method: read + * Signature: (Lcom/sun/jna/Pointer;JJ[JII)V */ -JNIEXPORT void JNICALL Java_com_sun_jna_Native_read__J_3JII - (JNIEnv *env, jclass UNUSED(cls), jlong addr, jlongArray arr, jint off, jint n) +JNIEXPORT void JNICALL Java_com_sun_jna_Native_read__Lcom_sun_jna_Pointer_2JJ_3JII + (JNIEnv *env, jclass UNUSED(cls), jobject UNUSED(pointer), jlong addr, jlong offset, jlongArray arr, jint off, jint n) { PSTART(); - (*env)->SetLongArrayRegion(env, arr, off, n, (jlong*)L2A(addr)); + (*env)->SetLongArrayRegion(env, arr, off, n, (jlong*)L2A(addr + offset)); PEND(env); } /* - * Class: Native - * Method: _read - * Signature: (J[SII)V + * Class: com_sun_jna_Native + * Method: read + * Signature: (Lcom/sun/jna/Pointer;JJ[SII)V */ -JNIEXPORT void JNICALL Java_com_sun_jna_Native_read__J_3SII - (JNIEnv *env, jclass UNUSED(cls), jlong addr, jshortArray arr, jint off, jint n) +JNIEXPORT void JNICALL Java_com_sun_jna_Native_read__Lcom_sun_jna_Pointer_2JJ_3SII + (JNIEnv *env, jclass UNUSED(cls), jobject UNUSED(pointer), jlong addr, jlong offset, jshortArray arr, jint off, jint n) { PSTART(); - (*env)->SetShortArrayRegion(env, arr, off, n, (jshort*)L2A(addr)); + (*env)->SetShortArrayRegion(env, arr, off, n, (jshort*)L2A(addr + offset)); PEND(env); } /* - * Class: Native - * Method: _getByte - * Signature: (J)B + * Class: com_sun_jna_Native + * Method: getByte + * Signature: (Lcom/sun/jna/Pointer;JJ)B */ JNIEXPORT jbyte JNICALL Java_com_sun_jna_Native_getByte -(JNIEnv * UNUSED_ENV(env), jclass UNUSED(cls), jlong addr) +(JNIEnv * UNUSED_ENV(env), jclass UNUSED(cls), jobject UNUSED(pointer), jlong addr, jlong offset) { jbyte res = 0; - MEMCPY(env, &res, L2A(addr), sizeof(res)); + MEMCPY(env, &res, L2A(addr + offset), sizeof(res)); return res; } /* - * Class: Native - * Method: _getChar - * Signature: (J)C + * Class: com_sun_jna_Native + * Method: getChar + * Signature: (Lcom/sun/jna/Pointer;JJ)C */ JNIEXPORT jchar JNICALL Java_com_sun_jna_Native_getChar -(JNIEnv * UNUSED_ENV(env), jclass UNUSED(cls), jlong addr) +(JNIEnv * UNUSED_ENV(env), jclass UNUSED(cls), jobject UNUSED(pointer), jlong addr, jlong offset) { wchar_t res = 0; - MEMCPY(env, &res, L2A(addr), sizeof(res)); + MEMCPY(env, &res, L2A(addr + offset), sizeof(res)); return (jchar)res; } /* - * Class: Native + * Class: com_sun_jna_Native * Method: _getPointer - * Signature: (J)Lcom/sun/jna/Pointer; + * Signature: (J)J */ JNIEXPORT jlong JNICALL Java_com_sun_jna_Native__1getPointer (JNIEnv *UNUSED_ENV(env), jclass UNUSED(cls), jlong addr) @@ -2442,10 +2498,10 @@ /* * Class: com_sun_jna_Native - * Method: _getDirectByteBuffer + * Method: getDirectByteBuffer * Signature: (JJ)Ljava/nio/ByteBuffer; */ -JNIEXPORT jobject JNICALL Java_com_sun_jna_Native_getDirectByteBuffer +JNIEXPORT jobject JNICALL Java_com_sun_jna_Native_getDirectByteBuffer__JJ (JNIEnv *env, jclass UNUSED(cls), jlong addr, jlong length) { #ifdef NO_NIO_BUFFERS @@ -2456,96 +2512,112 @@ } /* - * Class: Native - * Method: _getDouble - * Signature: (J)D + * Class: com_sun_jna_Native + * Method: getDirectByteBuffer + * Signature: (Lcom/sun/jna/Pointer;JJJ)Ljava/nio/ByteBuffer; + */ +JNIEXPORT jobject JNICALL Java_com_sun_jna_Native_getDirectByteBuffer__Lcom_sun_jna_Pointer_2JJJ + (JNIEnv *env, jclass UNUSED(cls), jobject UNUSED(pointer), jlong addr, jlong offset, jlong length) +{ +#ifdef NO_NIO_BUFFERS + return NULL; +#else + return (*env)->NewDirectByteBuffer(env, L2A(addr + offset), length); +#endif +} + +/* + * Class: com_sun_jna_Native + * Method: getDouble + * Signature: (Lcom/sun/jna/Pointer;JJ)D */ JNIEXPORT jdouble JNICALL Java_com_sun_jna_Native_getDouble -(JNIEnv * UNUSED_ENV(env), jclass UNUSED(cls), jlong addr) +(JNIEnv * UNUSED_ENV(env), jclass UNUSED(cls), jobject UNUSED(pointer), jlong addr, jlong offset) { jdouble res = 0; - MEMCPY(env, &res, L2A(addr), sizeof(res)); + MEMCPY(env, &res, L2A(addr + offset), sizeof(res)); return res; } /* - * Class: Native - * Method: _getFloat - * Signature: (J)F + * Class: com_sun_jna_Native + * Method: getFloat + * Signature: (Lcom/sun/jna/Pointer;JJ)F */ JNIEXPORT jfloat JNICALL Java_com_sun_jna_Native_getFloat -(JNIEnv * UNUSED_ENV(env), jclass UNUSED(cls), jlong addr) +(JNIEnv * UNUSED_ENV(env), jclass UNUSED(cls), jobject UNUSED(pointer), jlong addr, jlong offset) { jfloat res = 0; - MEMCPY(env, &res, L2A(addr), sizeof(res)); + MEMCPY(env, &res, L2A(addr + offset), sizeof(res)); return res; } /* - * Class: Native - * Method: _getInt - * Signature: (J)I + * Class: com_sun_jna_Native + * Method: getInt + * Signature: (Lcom/sun/jna/Pointer;JJ)I */ JNIEXPORT jint JNICALL Java_com_sun_jna_Native_getInt -(JNIEnv * UNUSED_ENV(env), jclass UNUSED(cls), jlong addr) +(JNIEnv * UNUSED_ENV(env), jclass UNUSED(cls), jobject UNUSED(pointer), jlong addr, jlong offset) { jint res = 0; - MEMCPY(env, &res, L2A(addr), sizeof(res)); + MEMCPY(env, &res, L2A(addr + offset), sizeof(res)); return res; } /* - * Class: Native - * Method: _getLong - * Signature: (J)J + * Class: com_sun_jna_Native + * Method: getLong + * Signature: (Lcom/sun/jna/Pointer;JJ)J */ JNIEXPORT jlong JNICALL Java_com_sun_jna_Native_getLong -(JNIEnv * UNUSED_ENV(env), jclass UNUSED(cls), jlong addr) +(JNIEnv * UNUSED_ENV(env), jclass UNUSED(cls), jobject UNUSED(pointer), jlong addr, jlong offset) { jlong res = 0; - MEMCPY(env, &res, L2A(addr), sizeof(res)); + MEMCPY(env, &res, L2A(addr + offset), sizeof(res)); return res; } /* - * Class: Native - * Method: _getShort - * Signature: (J)S + * Class: com_sun_jna_Native + * Method: getShort + * Signature: (Lcom/sun/jna/Pointer;JJ)S */ JNIEXPORT jshort JNICALL Java_com_sun_jna_Native_getShort -(JNIEnv * UNUSED_ENV(env), jclass UNUSED(cls), jlong addr) +(JNIEnv * UNUSED_ENV(env), jclass UNUSED(cls), jobject UNUSED(pointer), jlong addr, jlong offset) { jshort res = 0; - MEMCPY(env, &res, L2A(addr), sizeof(res)); + MEMCPY(env, &res, L2A(addr + offset), sizeof(res)); return res; } /* - * Class: Native + * Class: com_sun_jna_Native * Method: getWideString - * Signature: (JB)Ljava/lang/String; + * Signature: (Lcom/sun/jna/Pointer;JJ)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_sun_jna_Native_getWideString -(JNIEnv *env, jclass UNUSED(cls), jlong addr) +(JNIEnv *env, jclass UNUSED(cls), jobject UNUSED(pointer), jlong addr, jlong offset) { - return newJavaString(env, L2A(addr), NULL); + return newJavaString(env, L2A(addr + offset), NULL); } /* - * Class: Native + * Class: com_sun_jna_Native * Method: getStringBytes - * Signature: (JB)LB; + * Signature: (Lcom/sun/jna/Pointer;JJ)[B */ JNIEXPORT jbyteArray JNICALL Java_com_sun_jna_Native_getStringBytes -(JNIEnv *env, jclass UNUSED(cls), jlong addr) +(JNIEnv *env, jclass UNUSED(cls), jobject UNUSED(pointer), jlong baseaddr, jlong offset) { volatile jbyteArray bytes = 0; PSTART(); { - int len = (int)strlen(L2A(addr)); + void* addr = L2A(baseaddr + offset); + int len = (int)strlen(addr); bytes = (*env)->NewByteArray(env, len); if (bytes != 0) { - (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte *)L2A(addr)); + (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte *)addr); } else { throwByName(env, EOutOfMemory, "Can't allocate byte array"); @@ -2556,113 +2628,113 @@ } /* - * Class: Native + * Class: com_sun_jna_Native * Method: setMemory - * Signature: (JJB)V + * Signature: (Lcom/sun/jna/Pointer;JJJB)V */ JNIEXPORT void JNICALL Java_com_sun_jna_Native_setMemory -(JNIEnv *UNUSED_ENV(env), jclass UNUSED(cls), jlong addr, jlong count, jbyte value) +(JNIEnv *UNUSED_ENV(env), jclass UNUSED(cls), jobject UNUSED(pointer), jlong addr, jlong offset, jlong count, jbyte value) { - MEMSET(env, L2A(addr), (int)value, (size_t)count); + MEMSET(env, L2A(addr + offset), (int)value, (size_t)count); } /* - * Class: Native - * Method: _setByte - * Signature: (JB)V + * Class: com_sun_jna_Native + * Method: setByte + * Signature: (Lcom/sun/jna/Pointer;JJB)V */ JNIEXPORT void JNICALL Java_com_sun_jna_Native_setByte -(JNIEnv * UNUSED_ENV(env), jclass UNUSED(cls), jlong addr, jbyte value) +(JNIEnv * UNUSED_ENV(env), jclass UNUSED(cls), jobject UNUSED(pointer), jlong addr, jlong offset, jbyte value) { - MEMCPY(env, L2A(addr), &value, sizeof(value)); + MEMCPY(env, L2A(addr + offset), &value, sizeof(value)); } /* - * Class: Native - * Method: _setChar - * Signature: (JC)V + * Class: com_sun_jna_Native + * Method: setChar + * Signature: (Lcom/sun/jna/Pointer;JJC)V */ JNIEXPORT void JNICALL Java_com_sun_jna_Native_setChar -(JNIEnv * UNUSED_ENV(env), jclass UNUSED(cls), jlong addr, jchar value) +(JNIEnv * UNUSED_ENV(env), jclass UNUSED(cls), jobject UNUSED(pointer), jlong addr, jlong offset, jchar value) { wchar_t ch = value; - MEMCPY(env, L2A(addr), &ch, sizeof(ch)); + MEMCPY(env, L2A(addr + offset), &ch, sizeof(ch)); } /* - * Class: Native - * Method: _setNative - * Signature: (JJ)V + * Class: com_sun_jna_Native + * Method: setPointer + * Signature: (Lcom/sun/jna/Pointer;JJJ)V */ JNIEXPORT void JNICALL Java_com_sun_jna_Native_setPointer -(JNIEnv * UNUSED_ENV(env), jclass UNUSED(cls), jlong addr, jlong value) +(JNIEnv * UNUSED_ENV(env), jclass UNUSED(cls), jobject UNUSED(pointer), jlong addr, jlong offset, jlong value) { void *ptr = L2A(value); - MEMCPY(env, L2A(addr), &ptr, sizeof(void *)); + MEMCPY(env, L2A(addr + offset), &ptr, sizeof(void *)); } /* - * Class: Native - * Method: _setDouble - * Signature: (JD)V + * Class: com_sun_jna_Native + * Method: setDouble + * Signature: (Lcom/sun/jna/Pointer;JJD)V */ JNIEXPORT void JNICALL Java_com_sun_jna_Native_setDouble -(JNIEnv * UNUSED_ENV(env), jclass UNUSED(cls), jlong addr, jdouble value) +(JNIEnv * UNUSED_ENV(env), jclass UNUSED(cls), jobject UNUSED(pointer), jlong addr, jlong offset, jdouble value) { - MEMCPY(env, L2A(addr), &value, sizeof(value)); + MEMCPY(env, L2A(addr + offset), &value, sizeof(value)); } /* - * Class: Native - * Method: _setFloat - * Signature: (JF)V + * Class: com_sun_jna_Native + * Method: setFloat + * Signature: (Lcom/sun/jna/Pointer;JJF)V */ JNIEXPORT void JNICALL Java_com_sun_jna_Native_setFloat -(JNIEnv * UNUSED_ENV(env), jclass UNUSED(cls), jlong addr, jfloat value) +(JNIEnv * UNUSED_ENV(env), jclass UNUSED(cls), jobject UNUSED(pointer), jlong addr, jlong offset, jfloat value) { - MEMCPY(env, L2A(addr), &value, sizeof(value)); + MEMCPY(env, L2A(addr + offset), &value, sizeof(value)); } /* - * Class: Native - * Method: _setInt - * Signature: (JI)V + * Class: com_sun_jna_Native + * Method: setInt + * Signature: (Lcom/sun/jna/Pointer;JJI)V */ JNIEXPORT void JNICALL Java_com_sun_jna_Native_setInt -(JNIEnv * UNUSED_ENV(env), jclass UNUSED(cls), jlong addr, jint value) +(JNIEnv * UNUSED_ENV(env), jclass UNUSED(cls), jobject UNUSED(pointer), jlong addr, jlong offset, jint value) { - MEMCPY(env, L2A(addr), &value, sizeof(value)); + MEMCPY(env, L2A(addr + offset), &value, sizeof(value)); } /* - * Class: Native - * Method: _setLong - * Signature: (JJ)V + * Class: com_sun_jna_Native + * Method: setLong + * Signature: (Lcom/sun/jna/Pointer;JJJ)V */ JNIEXPORT void JNICALL Java_com_sun_jna_Native_setLong -(JNIEnv * UNUSED_ENV(env), jclass UNUSED(cls), jlong addr, jlong value) +(JNIEnv * UNUSED_ENV(env), jclass UNUSED(cls), jobject UNUSED(pointer), jlong addr, jlong offset, jlong value) { - MEMCPY(env, L2A(addr), &value, sizeof(value)); + MEMCPY(env, L2A(addr + offset), &value, sizeof(value)); } /* - * Class: Native - * Method: _setShort - * Signature: (JS)V + * Class: com_sun_jna_Native + * Method: setShort + * Signature: (Lcom/sun/jna/Pointer;JJS)V */ JNIEXPORT void JNICALL Java_com_sun_jna_Native_setShort -(JNIEnv * UNUSED_ENV(env), jclass UNUSED(cls), jlong addr, jshort value) +(JNIEnv * UNUSED_ENV(env), jclass UNUSED(cls), jobject UNUSED(pointer), jlong addr, jlong offset, jshort value) { - MEMCPY(env, L2A(addr), &value, sizeof(value)); + MEMCPY(env, L2A(addr + offset), &value, sizeof(value)); } /* - * Class: Native + * Class: com_sun_jna_Native * Method: setWideString - * Signature: (JLjava/lang/String;)V + * Signature: (Lcom/sun/jna/Pointer;JJLjava/lang/String;)V */ JNIEXPORT void JNICALL Java_com_sun_jna_Native_setWideString -(JNIEnv *env, jclass UNUSED(cls), jlong addr, jstring value) +(JNIEnv *env, jclass UNUSED(cls), jobject UNUSED(pointer), jlong addr, jlong offset, jstring value) { int len = (*env)->GetStringLength(env, value); const void* volatile str; @@ -2670,7 +2742,7 @@ str = newWideCString(env, value); if (str != NULL) { - MEMCPY(env, L2A(addr), str, size); + MEMCPY(env, L2A(addr + offset), str, size); free((void*)str); } } @@ -2711,6 +2783,7 @@ case com_sun_jna_Native_TYPE_LONG: return sizeof(long); case com_sun_jna_Native_TYPE_WCHAR_T: return sizeof(wchar_t); case com_sun_jna_Native_TYPE_SIZE_T: return sizeof(size_t); + case com_sun_jna_Native_TYPE_BOOL: return sizeof(bool); default: { char msg[MSG_SIZE]; @@ -2749,11 +2822,17 @@ throwByName(env, EUnsatisfiedLink, "Can't obtain static method dispose from class com.sun.jna.Native"); } - else if (!(MID_Native_fromNative + else if (!(MID_Native_fromNativeCallbackParam = (*env)->GetStaticMethodID(env, classNative, "fromNative", "(Ljava/lang/Class;Ljava/lang/Object;)Lcom/sun/jna/NativeMapped;"))) { throwByName(env, EUnsatisfiedLink, - "Can't obtain static method fromNative from class com.sun.jna.Native"); + "Can't obtain static method fromNative(Class, Object) from class com.sun.jna.Native"); + } + else if (!(MID_Native_fromNative + = (*env)->GetStaticMethodID(env, classNative, + "fromNative", "(Ljava/lang/reflect/Method;Ljava/lang/Object;)Lcom/sun/jna/NativeMapped;"))) { + throwByName(env, EUnsatisfiedLink, + "Can't obtain static method fromNative(Method, Object) from class com.sun.jna.Native"); } else if (!(MID_Native_nativeType = (*env)->GetStaticMethodID(env, classNative, @@ -2769,9 +2848,9 @@ } else if (!(MID_Native_fromNativeTypeMapped = (*env)->GetStaticMethodID(env, classNative, - "fromNative", "(Lcom/sun/jna/FromNativeConverter;Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/Object;"))) { + "fromNative", "(Lcom/sun/jna/FromNativeConverter;Ljava/lang/Object;Ljava/lang/reflect/Method;)Ljava/lang/Object;"))) { throwByName(env, EUnsatisfiedLink, - "Can't obtain static method fromNative from class com.sun.jna.Native"); + "Can't obtain static method fromNative(FromNativeConverter, Object, Method) from class com.sun.jna.Native"); } else if (!LOAD_CREF(env, Structure, "com/sun/jna/Structure")) { throwByName(env, EUnsatisfiedLink, @@ -2978,11 +3057,9 @@ const wchar_t* suffix = L"/bin/jawt.dll"; size_t len = wcslen(prop) + wcslen(suffix) + 1; path = (wchar_t*)alloca(len * sizeof(wchar_t)); -#ifdef _MSC_VER + swprintf(path, len, L"%s%s", prop, suffix); -#else - swprintf(path, L"%s%s", prop, suffix); -#endif + free((void *)prop); } #undef JAWT_NAME @@ -3088,15 +3165,17 @@ return A2L(addr); } +#ifdef HAVE_PROTECTION JNIEXPORT void JNICALL Java_com_sun_jna_Native_setProtected(JNIEnv *UNUSED(env), jclass UNUSED(classp), jboolean protect_access) { -#ifdef HAVE_PROTECTION _protect = protect_access; +} #else - // avoid compiler warning - protect_access = 0; -#endif +JNIEXPORT void JNICALL +Java_com_sun_jna_Native_setProtected(JNIEnv *UNUSED(env), jclass UNUSED(classp), jboolean UNUSED(protect_access)) { + /* Unsupported */ } +#endif jboolean is_protected() { @@ -3250,7 +3329,7 @@ } } if (md->from_native) (*env)->DeleteWeakGlobalRef(env, md->from_native); - if (md->closure_rclass) (*env)->DeleteWeakGlobalRef(env, md->closure_rclass); + if (md->closure_method) (*env)->DeleteGlobalRef(env, md->closure_method); free(md->arg_types); free(md->closure_arg_types); free(md->flags); @@ -3277,7 +3356,7 @@ jint rconversion, jlong closure_return_type, jlong return_type, - jclass closure_rclass, + jobject closure_method, jlong function, jint cc, jboolean throw_last_error, jobjectArray to_native, @@ -3315,7 +3394,7 @@ data->closure_arg_types = malloc(sizeof(ffi_type*) * (argc + 2)); data->closure_arg_types[0] = &ffi_type_pointer; data->closure_arg_types[1] = &ffi_type_pointer; - data->closure_rclass = NULL; + data->closure_method = NULL; data->flags = cvts ? malloc(sizeof(jint)*argc) : NULL; data->rflag = rconversion; data->to_native = NULL; @@ -3342,7 +3421,7 @@ if (closure_types) (*env)->ReleaseLongArrayElements(env, closure_atypes, closure_types, 0); if (cvts) (*env)->ReleaseIntArrayElements(env, conversions, cvts, 0); data->fptr = L2A(function); - data->closure_rclass = (*env)->NewWeakGlobalRef(env, closure_rclass); + data->closure_method = (*env)->NewGlobalRef(env, closure_method); status = ffi_prep_cif(closure_cif, abi, argc+2, closure_rtype, data->closure_arg_types); if (ffi_error(env, "Native method mapping", status)) { diff -Nru libjna-java-4.2.2/native/dispatch.h libjna-java-4.4.0/native/dispatch.h --- libjna-java-4.2.2/native/dispatch.h 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/native/dispatch.h 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007-2013 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

    - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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". */ #ifndef DISPATCH_H #define DISPATCH_H @@ -18,7 +29,7 @@ #include "ffi.h" #include "com_sun_jna_Function.h" #include "com_sun_jna_Native.h" -#if defined(__sun__) || defined(_AIX) +#if defined(__sun__) || defined(_AIX) || defined(__linux__) # include #endif #ifdef _WIN32 @@ -36,6 +47,9 @@ #define GET_LAST_ERROR() GetLastError() #define SET_LAST_ERROR(CODE) SetLastError(CODE) #else +#ifndef _XOPEN_SOURCE /* AIX power-aix 1 7 00F84C0C4C00 defins 700 */ +#define _XOPEN_SOURCE 600 +#endif #define GET_LAST_ERROR() errno #define SET_LAST_ERROR(CODE) (errno = (CODE)) #endif /* _WIN32 */ @@ -143,7 +157,7 @@ #if defined(_MSC_VER) #include "snprintf.h" -#define strdup _strdup +#define STRDUP _strdup #if defined(_WIN64) #define L2A(X) ((void *)(X)) #define A2L(X) ((jlong)(X)) @@ -151,6 +165,9 @@ #define L2A(X) ((void *)(unsigned long)(X)) #define A2L(X) ((jlong)(unsigned long)(X)) #endif +#else +#include +#define STRDUP strdup #endif /* Convenience macros */ @@ -216,7 +233,7 @@ extern void writeStructure(JNIEnv*, jobject); extern jclass getNativeType(JNIEnv*, jclass); extern void toNative(JNIEnv*, jobject, void*, size_t, jboolean, const char*); -extern jclass fromNative(JNIEnv*, jclass, ffi_type*, void*, jboolean, const char*); +extern jclass fromNativeCallbackParam(JNIEnv*, jclass, ffi_type*, void*, jboolean, const char*); typedef struct _AttachOptions { int daemon; diff -Nru libjna-java-4.2.2/native/dll-callback.c libjna-java-4.4.0/native/dll-callback.c --- libjna-java-4.2.2/native/dll-callback.c 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/native/dll-callback.c 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007-2012 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

    - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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". */ /* Must use mingw64 to compile this assembly code. ml64 can't generate the RIP-relative jumps we need. diff -Nru libjna-java-4.2.2/native/Makefile libjna-java-4.4.0/native/Makefile --- libjna-java-4.2.2/native/Makefile 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/native/Makefile 2017-03-14 19:31:03.000000000 +0000 @@ -50,8 +50,8 @@ -e 's/AIX.*/aix/g' \ -e 's/Linux.*/linux/g') -JNA_JNI_VERSION=4.0.1 # auto-generated by ant -CHECKSUM=1a6047467b59e8748f975e03016ce3d9 # auto-generated by ant +JNA_JNI_VERSION=5.1.0 # auto-generated by ant +CHECKSUM=74e8f8e397c43487738c5c1f1363498b # auto-generated by ant JAVA_INCLUDES=-I"$(JAVA_HOME)/include" \ -I"$(JAVA_HOME)/include/$(OS)" @@ -84,6 +84,16 @@ CC=gcc LD=$(CC) LIBS= +# CC_OPTS only applied to objects build for jnidispatch, not for libffi +# -Wno-unknown-warning-option +# => Suppress warning for unknown warnings +# -Werror => Treat warnings as errors +# -Wno-clobbered => Silence GCC warning about clobbered automatic variables. +# The "longjmp" case only happens in protect.h in the logic +# that implements "protected" mode. In that case an exception +# is raised and the value of the potentially clobbered +# variables is ignored. +LOC_CC_OPTS=-Wno-unknown-warning-option -Werror -Wno-clobbered # Default to Sun recommendations for JNI compilation COPT=-O2 -fno-omit-frame-pointer -fno-strict-aliasing CASM=-S @@ -200,26 +210,32 @@ endif # This will be overridden when called from ant ARCH=$(shell uname -m | sed 's/i.86/i386/g') -CDEFINES=-DHAVE_PROTECTION -DPSAPI_VERSION=1 -DFFI_BUILDING -DUNICODE -D_UNICODE +CDEFINES=-DPSAPI_VERSION=1 -DFFI_BUILDING -DUNICODE -D_UNICODE WINDRES=windres EXTRAOBJS=$(RSRC) STRIP=@echo LIBPFX= LIBSFX=.dll TESTLIB_TRUNC=$(BUILD)/testlib-truncated.dll + ifeq ($(ARCH),amd64) MINGW_PREFIX?=x86_64-w64-mingw32- FFI_CONFIG+=--host=x86_64-w64-mingw32 -# Need windres from mingw distribution, even if building with MSVC -WINDRES=$(MINGW_PREFIX)windres -MINGW=$(MINGW_PREFIX)gcc else -MINGW_PREFIX?=i686-pc-mingw32- +FFI_CONFIG+=--host=i686-w64-mingw32 +MINGW_PREFIX?=i686-w64-mingw32- endif +# Need windres from mingw distribution, even if building with MSVC +WINDRES=$(MINGW_PREFIX)windres +MINGW=$(MINGW_PREFIX)gcc ifeq ($(USE_MSVC),true) # MS compiler CC=$(FFI_SRC)/msvcc.sh +CDEFINES+=-DHAVE_PROTECTION +ifneq ($(DYNAMIC_LIBFFI),true) +CDEFINES+=-DUSE_STATIC_RTL +endif COPT= CPP=cl -nologo -EP LD=link @@ -237,21 +253,11 @@ # Mingw compiler LDFLAGS=-o $@ -shared FFI_ENV+=CXXCPP="$(CPP)" - -ifneq ($(ARCH),amd64) CC=$(MINGW_PREFIX)gcc CPP=$(MINGW_PREFIX)gcc -E LDFLAGS+=-Wl,--add-stdcall-alias -LIBS=-lpsapi -else -# mingw64 lacks SEH, so MSVC build is preferred -CC=$(MINGW) -# No SEH under mingw64, thus no HAVE_PROTECTION -CDEFINES=-DPSAPI_VERSION=1 -LD = $(CC) LIBS= -lmingwex -lpsapi -lkernel32 -lmsvcrt endif -endif endif @@ -279,7 +285,7 @@ ifeq ($(ARCH),) ARCH=$(shell uname -p) endif -PCFLAGS+=-fPIC +PCFLAGS+=-fPIC -std=gnu99 CDEFINES+=-DHAVE_PROTECTION -DFFI_MMAP_EXEC_WRIT -DUSE_DEFAULT_LIBNAME_ENCODING ifeq ($(ARCH), sparcv9) # alter CC instead of PCFLAGS, since we need to pass it down to libffi @@ -397,13 +403,13 @@ $(BUILD)/%.o : %.c dispatch.h protect.h $(FFI_LIB) @mkdir -p $(BUILD) ifneq ($(SDKROOT),) - $(CC) -arch $(ARCH) $(CFLAGS) -c $< -o $@.$(ARCH) + $(CC) $(LOC_CC_OPTS) -arch $(ARCH) $(CFLAGS) -c $< -o $@.$(ARCH) for arch in $(ALT_ARCHS); do \ - $(CC) -arch $$arch -I$(BUILD)/libffi.$$arch/include $(CFLAGS) -c $< -o $@.$$arch; \ + $(CC) $(LOC_CC_OPTS) -arch $$arch -I$(BUILD)/libffi.$$arch/include $(CFLAGS) -c $< -o $@.$$arch; \ done lipo -create -output $@ $@.* else - $(CC) $(CFLAGS) -c $< $(COUT) + $(CC) $(CFLAGS) $(LOC_CC_OPTS) -c $< $(COUT) endif all: $(LIBRARY) $(TESTLIB) $(TESTLIB2) $(TESTLIB_JAR) $(TESTLIB_PATH) $(TESTLIB_TRUNC) diff -Nru libjna-java-4.2.2/native/pom.xml libjna-java-4.4.0/native/pom.xml --- libjna-java-4.2.2/native/pom.xml 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/native/pom.xml 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,57 @@ + + + + 4.0.0 + + + net.java.dev.jna + jna-parent + 4.3.0-SNAPHSOT + ../parent + + + jna-native + pom + + net.java.dev.jna:jna-native + + + + + maven-antrun-plugin + + + compile-native-library + package + + run + + + + + + + + + + + + + + maven-install-plugin + + true + + + + maven-deploy-plugin + + true + + + + + diff -Nru libjna-java-4.2.2/native/protect.h libjna-java-4.4.0/native/protect.h --- libjna-java-4.2.2/native/protect.h 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/native/protect.h 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

    - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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". */ #ifndef PROTECT_H #define PROTECT_H @@ -44,6 +55,7 @@ #ifdef __GNUC__ #include #else +#include // copied from mingw header typedef EXCEPTION_DISPOSITION (*PEXCEPTION_HANDLER) (struct _EXCEPTION_RECORD*, void*, struct _CONTEXT*, void*); diff -Nru libjna-java-4.2.2/native/snprintf.h libjna-java-4.4.0/native/snprintf.h --- libjna-java-4.2.2/native/snprintf.h 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/native/snprintf.h 2017-03-14 19:31:03.000000000 +0000 @@ -1,5 +1,6 @@ #ifndef _SNPRINTF_H #define _SNPRINTF_H +#if _MSC_VER < 1900 // Before Visual Studio 2015 // snprintf on windows is broken; always nul-terminate manually // DO NOT rely on the return value... static int snprintf(char * str, size_t size, const char * format, ...) { @@ -10,4 +11,5 @@ va_end(ap); return retval; } +#endif #endif /* _SNPRINTF_H */ diff -Nru libjna-java-4.2.2/native/testlib2.c libjna-java-4.4.0/native/testlib2.c --- libjna-java-4.2.2/native/testlib2.c 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/native/testlib2.c 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007-2008 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

    - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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". */ /* Simple library with a dependency. */ diff -Nru libjna-java-4.2.2/native/testlib.c libjna-java-4.4.0/native/testlib.c --- libjna-java-4.2.2/native/testlib.c 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/native/testlib.c 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007-2013 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

    - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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". */ /* Native library implementation to support JUnit tests. */ @@ -855,12 +866,14 @@ return len; } +#include "ffi.h" + EXPORT int32_t -addInt32VarArgs(const char *fmt, ...) { +addVarArgs(const char *fmt, ...) { va_list ap; int32_t sum = 0; va_start(ap, fmt); - + while (*fmt) { switch (*fmt++) { case 'd': @@ -872,6 +885,10 @@ case 'c': sum += (int) va_arg(ap, int); break; + case 'f': // float (promoted to ‘double’ when passed through ‘...’) + case 'g': // double + sum += (int) va_arg(ap, double); + break; default: break; } @@ -906,6 +923,16 @@ char* cp; va_list ap; va_start(ap, fmt); + cp = va_arg(ap, char *); + va_end(ap); + return cp; +} + +EXPORT char * +returnStringVarArgs2(const char *fmt, ...) { + char* cp; + va_list ap; + va_start(ap, fmt); cp = va_arg(ap, char *); va_end(ap); return cp; diff -Nru libjna-java-4.2.2/nbproject/project.xml libjna-java-4.4.0/nbproject/project.xml --- libjna-java-4.2.2/nbproject/project.xml 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/nbproject/project.xml 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,107 @@ + + + org.netbeans.modules.ant.freeform + + + JNA + + + + JNA + + + + + . + UTF-8 + + + + java + src + UTF-8 + + + + java + test + UTF-8 + + + + java + ant-elfanalyser-src + UTF-8 + + + + + jar + + + clean + + + javadoc + + + test + + + clean + jar + + + + + + + src + + + + test + + + + ant-elfanalyser-src + + + build.xml + + + + + + + + + + + + + + + src + src + 1.5 + + + test + + lib/hamcrest-core-1.3.jar:lib/junit.jar:lib/test/dom4j-1.6.1.jar:lib/test/guava-11.0.2.jar:lib/test/javassist-3.12.1.GA.jar:lib/test/reflections-0.9.8.jar:lib/test/slf4j-api-1.6.1.jar:src + 1.5 + + + ant-elfanalyser-src + src:lib/ant.jar + 1.5 + + + + diff -Nru libjna-java-4.2.2/parent/build-base.xml libjna-java-4.4.0/parent/build-base.xml --- libjna-java-4.2.2/parent/build-base.xml 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/parent/build-base.xml 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,99 @@ + + + + Holds common imported definitions for ANT build.xml file(s) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru libjna-java-4.2.2/parent/build-compile.xml libjna-java-4.4.0/parent/build-compile.xml --- libjna-java-4.2.2/parent/build-compile.xml 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/parent/build-compile.xml 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,144 @@ + + + + Holds common imported definitions for ANT build.xml file(s) + that build/generate artifacts + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru libjna-java-4.2.2/parent/pom.xml libjna-java-4.4.0/parent/pom.xml --- libjna-java-4.2.2/parent/pom.xml 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/parent/pom.xml 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,307 @@ + + + 4.0.0 + + net.java.dev.jna + jna-parent + 4.3.0-SNAPHSOT + pom + + net.java.dev.jna:jna-parent + https://github.com/java-native-access/jna + + + LGPL, version 2.1 + http://www.gnu.org/licenses/licenses.html + repo + + + Apache License v2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + twall + Timothy Wall + + Owner + + + + + + ${min.required.maven.version} + + + + ../native + + + + scm:git:https://github.com/java-native-access/jna + scm:git:ssh://git@github.com/java-native-access/jna.git + https://github.com/java-native-access/jna + + + + UTF-8 + + + + 1 + 5 + 0 + + ${jvm.major.version}.${jvm.minor.version} + ${javac.source} + ${javac.source} + ${javac.source} + + ${javac.source} + ${javac.target} + ${javac.target} + ${javac.target} + + 3.2 + 2.19 + + 1.9.6 + 1.16 + 1.0b3 + + 4.12 + + 2.10.1 + + + + + + junit + junit + ${junit.version} + test + + + + + + package + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + org.apache.maven.plugins + maven-dependency-plugin + [1.0,) + + copy + copy-dependencies + + + + + + + + + org.codehaus.gmaven + gmaven-plugin + [1.0,) + + compile + execute + testCompile + + + + + + + + + + + + + maven-compiler-plugin + 3.3 + + ${javac.source} + ${javac.target} + -Xlint:-serial + + + + + maven-jar-plugin + 2.6 + + + + true + true + + true + true + + + + ${java.version} + ${java.vm.version} + ${user.name} + + ${maven.build.timestamp} + ${maven.version} + + + + + + + maven-install-plugin + 2.5.2 + + + + maven-dependency-plugin + 2.10 + + + install + install + + sources + + + + + + + maven-clean-plugin + 2.6.1 + + + + maven-deploy-plugin + 2.8.2 + + + + maven-antrun-plugin + 1.8 + + + org.apache.ant + ant + ${ant.version} + + + com.sun + tools + ${javac.source} + system + ${java.home}/../lib/tools.jar + + + + + + maven-javadoc-plugin + ${javadoc.plugin.version} + + + + + + maven-enforcer-plugin + 1.4 + + + enforce-versions + + enforce + + + + + + + [${min.required.maven.version},) + + + [${javac.target},) + + + + + + + maven-source-plugin + 2.4 + + + attach-sources + verify + + jar-no-fork + + + + + + + maven-surefire-plugin + ${surefire.plugin.version} + + + **/*Test.java + + + + + + + + + + maven-project-info-reports-plugin + 2.2 + + + + maven-surefire-report-plugin + ${surefire.plugin.version} + + + + maven-javadoc-plugin + ${javadoc.plugin.version} + + + + + + + fast + + true + true + + + + diff -Nru libjna-java-4.2.2/pom-jna-platform.xml libjna-java-4.4.0/pom-jna-platform.xml --- libjna-java-4.2.2/pom-jna-platform.xml 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/pom-jna-platform.xml 2017-03-14 19:31:03.000000000 +0000 @@ -20,7 +20,7 @@ repo - ASL, version 2 + Apache License v2.0 http://www.apache.org/licenses/LICENSE-2.0.txt repo @@ -40,6 +40,14 @@ Owner + + mblaesing@doppel-helix.eu + Matthias Bläsing + https://github.com/matthiasblaesing/ + + Developer + + diff -Nru libjna-java-4.2.2/pom-jna.xml libjna-java-4.4.0/pom-jna.xml --- libjna-java-4.2.2/pom-jna.xml 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/pom-jna.xml 2017-03-14 19:31:03.000000000 +0000 @@ -20,7 +20,7 @@ repo - ASL, version 2 + Apache License v2.0 http://www.apache.org/licenses/LICENSE-2.0.txt repo @@ -40,6 +40,14 @@ Owner + + mblaesing@doppel-helix.eu + Matthias Bläsing + https://github.com/matthiasblaesing/ + + Developer + + - \ No newline at end of file + diff -Nru libjna-java-4.2.2/README.md libjna-java-4.4.0/README.md --- libjna-java-4.2.2/README.md 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/README.md 2017-03-14 19:31:03.000000000 +0000 @@ -5,7 +5,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/4.2.1). Please read the [overview](http://java-native-access.github.io/jna/4.2.1/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/4.4.0/javadoc/). Please read the [overview](http://java-native-access.github.io/jna/4.4.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. @@ -37,6 +37,7 @@ - [USB for Java](https://launchpad.net/libusb4j) by Mario Boikov. - [Waffle](https://github.com/dblock/waffle): Enables SSO on Windows in Java applications, by Daniel Doubrovkine. - [leveldb-jna](https://github.com/protonail/leveldb-jna): Cross-platform JNA based adapter for LevelDB (used in [Keylord](http://protonail.com/products/keylord)). +- [Java OpenVR Bindings](https://github.com/java-graphics/openvr). *Interesting Investigations/Experiments* @@ -56,13 +57,13 @@ Download ======== -Version 4.2.1 +Version 4.4.0 * [![Maven Central](https://maven-badges.herokuapp.com/maven-central/net.java.dev.jna/jna/badge.svg)](https://maven-badges.herokuapp.com/maven-central/net.java.dev.jna/jna)   - [jna.jar](https://maven.java.net/content/repositories/releases/net/java/dev/jna/jna/4.2.1/jna-4.2.1.jar) + [jna.jar](http://repo1.maven.org/maven2/net/java/dev/jna/jna/4.4.0/jna-4.4.0.jar) * [![Maven Central](https://maven-badges.herokuapp.com/maven-central/net.java.dev.jna/jna-platform/badge.svg)](https://maven-badges.herokuapp.com/maven-central/net.java.dev.jna/jna-platform)   - [jna-platform.jar](https://maven.java.net/content/repositories/releases/net/java/dev/jna/jna-platform/4.2.1/jna-platform-4.2.1.jar) + [jna-platform.jar](http://repo1.maven.org/maven2/net/java/dev/jna/jna-platform/4.4.0/jna-platform-4.4.0.jar) Features ======== @@ -123,12 +124,12 @@ * [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/4.2.1/overview-summary.html#crash-protection) +* [Avoiding Crashes](http://java-native-access.github.io/jna/4.4.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/4.2.1/). +The definitive JNA reference is in the [JavaDoc](http://java-native-access.github.io/jna/4.4.0/javadoc/). Developers ========== diff -Nru libjna-java-4.2.2/src/com/sun/jna/AltCallingConvention.java libjna-java-4.4.0/src/com/sun/jna/AltCallingConvention.java --- libjna-java-4.2.2/src/com/sun/jna/AltCallingConvention.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/AltCallingConvention.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

    - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; diff -Nru libjna-java-4.2.2/src/com/sun/jna/Callback.java libjna-java-4.4.0/src/com/sun/jna/Callback.java --- libjna-java-4.2.2/src/com/sun/jna/Callback.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/Callback.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,35 +1,47 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

    - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.Arrays; -import java.util.Collection; +import java.util.Collections; +import java.util.List; -/** All callback definitions must derive from this interface. Any +/** All callback definitions must derive from this interface. Any * derived interfaces must define a single public method (which may not be named * "hashCode", "equals", or "toString"), or one public method named "callback". * You are responsible for deregistering your callback (if necessary) * in its {@link Object#finalize} method. If native code attempts to call - * a callback which has been GC'd, you will likely crash the VM. If + * a callback which has been GC'd, you will likely crash the VM. If * there is no method to deregister the callback (e.g. atexit * in the C library), you must ensure that you always keep a live reference * to the callback object.

    * A callback should generally never throw an exception, since it doesn't * necessarily have an encompassing Java environment to catch it. Any * exceptions thrown will be passed to the default callback exception - * handler. + * handler. */ -public interface Callback { +public interface Callback { interface UncaughtExceptionHandler { /** Method invoked when the given callback throws an uncaught * exception.

    @@ -43,8 +55,8 @@ of those in {@link #FORBIDDEN_NAMES}. */ String METHOD_NAME = "callback"; + /** These method names may not be used for a callback method. */ - Collection FORBIDDEN_NAMES = Arrays.asList(new String[] { - "hashCode", "equals", "toString", - }); -} + List FORBIDDEN_NAMES = Collections.unmodifiableList( + Arrays.asList("hashCode", "equals", "toString")); +} diff -Nru libjna-java-4.2.2/src/com/sun/jna/CallbackParameterContext.java libjna-java-4.4.0/src/com/sun/jna/CallbackParameterContext.java --- libjna-java-4.2.2/src/com/sun/jna/CallbackParameterContext.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/CallbackParameterContext.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; @@ -19,7 +30,7 @@ private Method method; private Object[] args; private int index; - CallbackParameterContext(Class javaType, Method m, Object[] args, int index) { + CallbackParameterContext(Class javaType, Method m, Object[] args, int index) { super(javaType); this.method = m; this.args = args; diff -Nru libjna-java-4.2.2/src/com/sun/jna/CallbackProxy.java libjna-java-4.4.0/src/com/sun/jna/CallbackProxy.java --- libjna-java-4.2.2/src/com/sun/jna/CallbackProxy.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/CallbackProxy.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Wayne Meissner, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; @@ -19,12 +30,12 @@ */ public interface CallbackProxy extends Callback { - /** This is the callback method invoked from native code. + /** This is the callback method invoked from native code. * It must not throw any exceptions whatsoever. */ Object callback(Object[] args); /** Returns the types of the parameters to the callback method. */ - Class[] getParameterTypes(); + Class[] getParameterTypes(); /** Returns the type of the callback method's return value. */ - Class getReturnType(); + Class getReturnType(); } \ No newline at end of file diff -Nru libjna-java-4.2.2/src/com/sun/jna/CallbackReference.java libjna-java-4.4.0/src/com/sun/jna/CallbackReference.java --- libjna-java-4.2.2/src/com/sun/jna/CallbackReference.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/CallbackReference.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007-2013 Timothy Wall, 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * You can freely decide which license you want to apply to + * the project. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; @@ -19,10 +30,12 @@ import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; @@ -31,59 +44,70 @@ import com.sun.jna.win32.DLLCallback; /** Provides a reference to an association between a native callback closure - * and a Java {@link Callback} closure. + * and a Java {@link Callback} closure. */ -class CallbackReference extends WeakReference { - - static final Map callbackMap = new WeakHashMap(); - static final Map directCallbackMap = new WeakHashMap(); - static final Map pointerCallbackMap = new WeakHashMap(); - static final Map allocations = new WeakHashMap(); - private static final Map allocatedMemory = Collections.synchronizedMap(new WeakHashMap()); +public class CallbackReference extends WeakReference { + static final Map callbackMap = new WeakHashMap(); + static final Map directCallbackMap = new WeakHashMap(); + static final Map> pointerCallbackMap = new WeakHashMap>(); + // Track memory allocations associated with this closure (usually String args) + static final Map allocations = new WeakHashMap(); + // Global map of allocated closures to facilitate centralized cleanup + private static final Map> allocatedMemory = + Collections.synchronizedMap(new WeakHashMap>()); private static final Method PROXY_CALLBACK_METHOD; - + static { try { PROXY_CALLBACK_METHOD = CallbackProxy.class.getMethod("callback", new Class[] { Object[].class }); - } - catch(Exception e) { + } catch(Exception e) { throw new Error("Error looking up CallbackProxy.callback() method"); } } - private static final Map initializers = new WeakHashMap(); - static void setCallbackThreadInitializer(Callback cb, CallbackThreadInitializer initializer) { - synchronized(callbackMap) { + private static final Map initializers = new WeakHashMap(); + /** + * @param cb The {@link Callback} instance + * @param initializer The {@link CallbackThreadInitializer} - if {@code null} then the + * associated initializer instance is removed + * @return The previous initializer instance (may be {@code null}) + */ + static CallbackThreadInitializer setCallbackThreadInitializer(Callback cb, CallbackThreadInitializer initializer) { + synchronized(initializers) { if (initializer != null) { - initializers.put(cb, initializer); - } - else { - initializers.remove(cb); + return initializers.put(cb, initializer); + } else { + return initializers.remove(cb); } } } static class AttachOptions extends Structure { + public static final List FIELDS = createFieldsOrder("daemon", "detach", "name"); public boolean daemon; public boolean detach; public String name; // Thread name must be UTF8-encoded - { setStringEncoding("utf8"); } - protected List getFieldOrder() { - return Arrays.asList(new String[] { "daemon", "detach", "name", }); + { + setStringEncoding("utf8"); + } + + @Override + protected List getFieldOrder() { + return FIELDS; } } - /** Called from native code to initialize a callback thread. */ + /* Called from native code to initialize a callback thread. */ private static ThreadGroup initializeThread(Callback cb, AttachOptions args) { CallbackThreadInitializer init = null; if (cb instanceof DefaultCallbackProxy) { cb = ((DefaultCallbackProxy)cb).getCallback(); } - synchronized(callbackMap) { - init = (CallbackThreadInitializer)initializers.get(cb); + synchronized(initializers) { + init = initializers.get(cb); } ThreadGroup group = null; if (init != null) { @@ -103,23 +127,23 @@ * @throws IllegalStateException if the given pointer has already been * mapped to a callback of a different type. */ - public static Callback getCallback(Class type, Pointer p) { + public static Callback getCallback(Class type, Pointer p) { return getCallback(type, p, false); } - private static Callback getCallback(Class type, Pointer p, boolean direct) { + private static Callback getCallback(Class type, Pointer p, boolean direct) { if (p == null) { return null; } if (!type.isInterface()) throw new IllegalArgumentException("Callback type must be an interface"); - Map map = direct ? directCallbackMap : callbackMap; - synchronized(callbackMap) { + Map map = direct ? directCallbackMap : callbackMap; + synchronized(pointerCallbackMap) { Callback cb = null; - Reference ref = (Reference)pointerCallbackMap.get(p); + Reference ref = pointerCallbackMap.get(p); if (ref != null) { - cb = (Callback)ref.get(); + cb = ref.get(); if (cb != null && !type.isAssignableFrom(cb.getClass())) { throw new IllegalStateException("Pointer " + p + " already mapped to " + cb + ".\nNative code may be re-using a default function pointer" @@ -130,37 +154,39 @@ } 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); cb = (Callback)Proxy.newProxyInstance(type.getClassLoader(), new Class[] { type }, h); // No CallbackReference for this callback - map.put(cb, null); - pointerCallbackMap.put(p, new WeakReference(cb)); + map.remove(cb); + pointerCallbackMap.put(p, new WeakReference(cb)); return cb; } } - + Pointer cbstruct; Pointer trampoline; // Keep a reference to the proxy to avoid premature GC of it CallbackProxy proxy; Method method; + int callingConvention; private CallbackReference(Callback callback, int callingConvention, boolean direct) { super(callback); TypeMapper mapper = Native.getTypeMapper(callback.getClass()); - Class[] nativeParamTypes; - Class returnType; + this.callingConvention = callingConvention; + Class[] nativeParamTypes; + Class returnType; // Check whether direct mapping may be used, or whether // we need to fall back to conventional mapping boolean ppc = Platform.isPPC(); if (direct) { Method m = getCallbackMethod(callback); - Class[] ptypes = m.getParameterTypes(); + Class[] ptypes = m.getParameterTypes(); for (int i=0;i < ptypes.length;i++) { // varargs w/FP args via ffi_call fails on ppc (darwin) - if (ppc && (ptypes[i] == float.class + if (ppc && (ptypes[i] == float.class || ptypes[i] == double.class)) { direct = false; break; @@ -180,6 +206,7 @@ } String encoding = Native.getStringEncoding(callback.getClass()); + long peer = 0; if (direct) { method = getCallbackMethod(callback); nativeParamTypes = method.getParameterTypes(); @@ -188,14 +215,11 @@ if (callback instanceof DLLCallback) { flags |= Native.CB_OPTION_IN_DLL; } - long peer = Native.createNativeCallback(callback, method, - nativeParamTypes, returnType, - callingConvention, flags, - encoding); - cbstruct = peer != 0 ? new Pointer(peer) : null; - allocatedMemory.put(this, new WeakReference(this)); - } - else { + peer = Native.createNativeCallback(callback, method, + nativeParamTypes, returnType, + callingConvention, flags, + encoding); + } else { if (callback instanceof CallbackProxy) { proxy = (CallbackProxy)callback; } @@ -205,7 +229,7 @@ nativeParamTypes = proxy.getParameterTypes(); returnType = proxy.getReturnType(); - // Generate a list of parameter types that the native code can + // Generate a list of parameter types that the native code can // handle. Let the CallbackProxy do any further conversion // to match the true Java callback method signature if (mapper != null) { @@ -223,7 +247,7 @@ for (int i=0;i < nativeParamTypes.length;i++) { nativeParamTypes[i] = getNativeType(nativeParamTypes[i]); if (!isAllowableNativeType(nativeParamTypes[i])) { - String msg = "Callback argument " + nativeParamTypes[i] + String msg = "Callback argument " + nativeParamTypes[i] + " requires custom type conversion"; throw new IllegalArgumentException(msg); } @@ -236,25 +260,24 @@ } int flags = callback instanceof DLLCallback ? Native.CB_OPTION_IN_DLL : 0; - long peer = Native.createNativeCallback(proxy, PROXY_CALLBACK_METHOD, - nativeParamTypes, returnType, - callingConvention, flags, - encoding); - cbstruct = peer != 0 ? new Pointer(peer) : null; + peer = Native.createNativeCallback(proxy, PROXY_CALLBACK_METHOD, + nativeParamTypes, returnType, + callingConvention, flags, + encoding); } + cbstruct = peer != 0 ? new Pointer(peer) : null; + allocatedMemory.put(this, new WeakReference(this)); } - - private Class getNativeType(Class cls) { + + private Class getNativeType(Class cls) { if (Structure.class.isAssignableFrom(cls)) { // Make sure we can instantiate an argument of this type Structure.validate(cls); if (!Structure.ByValue.class.isAssignableFrom(cls)) return Pointer.class; - } - else if (NativeMapped.class.isAssignableFrom(cls)) { + } else if (NativeMapped.class.isAssignableFrom(cls)) { return NativeMappedConverter.getInstance(cls).nativeType(); - } - else if (cls == String.class + } else if (cls == String.class || cls == WString.class || cls == String[].class || cls == WString[].class @@ -263,7 +286,7 @@ } return cls; } - + private static Method checkMethod(Method m) { if (m.getParameterTypes().length > Function.MAX_NARGS) { String msg = "Method signature exceeds the maximum " @@ -273,21 +296,22 @@ return m; } - /** Find the first instance of an interface which implements the Callback + /* + * Find the first instance of an interface which implements the Callback * interface or an interface derived from Callback, which defines an * appropriate callback method. */ - static Class findCallbackClass(Class type) { + static Class findCallbackClass(Class type) { if (!Callback.class.isAssignableFrom(type)) { throw new IllegalArgumentException(type.getName() + " is not derived from com.sun.jna.Callback"); } if (type.isInterface()) { return type; } - Class[] ifaces = type.getInterfaces(); + Class[] ifaces = type.getInterfaces(); for (int i=0;i < ifaces.length;i++) { if (Callback.class.isAssignableFrom(ifaces[i])) { - try { + try { // Make sure it's got a recognizable callback method getCallbackMethod(ifaces[i]); return ifaces[i]; @@ -302,26 +326,27 @@ } return type; } - + private static Method getCallbackMethod(Callback callback) { return getCallbackMethod(findCallbackClass(callback.getClass())); } - private static Method getCallbackMethod(Class cls) { + 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 - for (Iterator i=pmethods.iterator();i.hasNext();) { - Method m = (Method)i.next(); + // Remove Object methods disallowed as callback method names + for (Iterator i=pmethods.iterator();i.hasNext();) { + Method m = i.next(); if (Callback.FORBIDDEN_NAMES.contains(m.getName())) { i.remove(); } } - Method[] methods = (Method[])pmethods.toArray(new Method[pmethods.size()]); + + Method[] methods = pmethods.toArray(new Method[pmethods.size()]); if (methods.length == 1) { return checkMethod(methods[0]); } @@ -335,7 +360,7 @@ + "or one public method named '" + Callback.METHOD_NAME + "'"; throw new IllegalArgumentException(msg); } - + /** Set the behavioral options for this callback. */ private void setCallbackOptions(int options) { cbstruct.setInt(Pointer.SIZE, options); @@ -348,31 +373,37 @@ } return trampoline; } - + /** Free native resources associated with this callback when GC'd. */ + @Override protected void finalize() { dispose(); } - + /** Free native resources associated with this callback. */ protected synchronized void dispose() { if (cbstruct != null) { - Native.freeNativeCallback(cbstruct.peer); - cbstruct.peer = 0; - cbstruct = null; - allocatedMemory.remove(this); + try { + Native.freeNativeCallback(cbstruct.peer); + } finally { + cbstruct.peer = 0; + cbstruct = null; + allocatedMemory.remove(this); + } } } /** Dispose of all memory allocated for callbacks. */ static void disposeAll() { - for (Iterator i=allocatedMemory.keySet().iterator();i.hasNext();) { - ((Memory)i.next()).dispose(); + // use a copy since dispose() modifes the map + Collection refs = new LinkedList(allocatedMemory.keySet()); + for (CallbackReference r : refs) { + r.dispose(); } } private Callback getCallback() { - return (Callback)get(); + return get(); } /** If the callback is one we generated to wrap a native function pointer, @@ -387,9 +418,9 @@ } return null; } - + /** Return a {@link Pointer} to the native function address for the - * given callback. + * given callback. */ public static Pointer getFunctionPointer(Callback cb) { return getFunctionPointer(cb, false); @@ -404,15 +435,20 @@ if ((fp = getNativeFunctionPointer(cb)) != null) { return fp; } + Map options = Native.getLibraryOptions(cb.getClass()); int callingConvention = cb instanceof AltCallingConvention - ? Function.ALT_CONVENTION : Function.C_CONVENTION; - Map map = direct ? directCallbackMap : callbackMap; - synchronized(callbackMap) { - CallbackReference cbref = (CallbackReference)map.get(cb); + ? Function.ALT_CONVENTION + : (options != null && options.containsKey(Library.OPTION_CALLING_CONVENTION) + ? ((Integer)options.get(Library.OPTION_CALLING_CONVENTION)).intValue() + : Function.C_CONVENTION); + + Map map = direct ? directCallbackMap : callbackMap; + synchronized(pointerCallbackMap) { + CallbackReference cbref = map.get(cb); if (cbref == null) { cbref = new CallbackReference(cb, callingConvention, direct); map.put(cb, cbref); - pointerCallbackMap.put(cbref.getTrampoline(), new WeakReference(cb)); + pointerCallbackMap.put(cbref.getTrampoline(), new WeakReference(cb)); if (initializers.containsKey(cb)) { cbref.setCallbackOptions(Native.CB_HAS_INITIALIZER); } @@ -429,8 +465,8 @@ public DefaultCallbackProxy(Method callbackMethod, TypeMapper mapper, String encoding) { this.callbackMethod = callbackMethod; this.encoding = encoding; - Class[] argTypes = callbackMethod.getParameterTypes(); - Class returnType = callbackMethod.getReturnType(); + Class[] argTypes = callbackMethod.getParameterTypes(); + Class returnType = callbackMethod.getReturnType(); fromNative = new FromNativeConverter[argTypes.length]; if (NativeMapped.class.isAssignableFrom(returnType)) { toNative = NativeMappedConverter.getInstance(returnType); @@ -455,29 +491,28 @@ } } } - + public Callback getCallback() { return CallbackReference.this.getCallback(); } private Object invokeCallback(Object[] args) { - Class[] paramTypes = callbackMethod.getParameterTypes(); + Class[] paramTypes = callbackMethod.getParameterTypes(); Object[] callbackArgs = new Object[args.length]; - + // convert basic supported types to appropriate Java parameter types for (int i=0;i < args.length;i++) { - Class type = paramTypes[i]; + Class type = paramTypes[i]; Object arg = args[i]; if (fromNative[i] != null) { - FromNativeContext context = + FromNativeContext context = new CallbackParameterContext(type, callbackMethod, args, i); callbackArgs[i] = fromNative[i].fromNative(arg, context); - } - else { + } else { callbackArgs[i] = convertArgument(arg, type); } } - + Object result = null; Callback cb = DefaultCallbackProxy.this.getCallback(); if (cb != null) { @@ -504,12 +539,13 @@ return result; } - /** Called from native code. All arguments are in an array of + /** Called from native code. All arguments are in an array of * Object as the first argument. Converts all arguments to types * required by the actual callback method signature, and converts * the result back into an appropriate native type. - * This method must not throw exceptions. + * This method must not throw exceptions. */ + @Override public Object callback(Object[] args) { try { return invokeCallback(args); @@ -523,7 +559,7 @@ /** Convert argument from its basic native type to the given * Java parameter type. */ - private Object convertArgument(Object value, Class dstType) { + private Object convertArgument(Object value, Class dstType) { if (value instanceof Pointer) { if (dstType == String.class) { value = ((Pointer)value).getString(0, encoding); @@ -538,7 +574,7 @@ value = ((Pointer)value).getWideStringArray(0); } else if (Callback.class.isAssignableFrom(dstType)) { - value = CallbackReference.this.getCallback(dstType, (Pointer)value); + value = CallbackReference.getCallback(dstType, (Pointer)value); } else if (Structure.class.isAssignableFrom(dstType)) { // If passed by value, don't hold onto the pointer, which @@ -550,8 +586,7 @@ s.getPointer().write(0, buf, 0, buf.length); s.read(); value = s; - } - else { + } else { Structure s = Structure.newInstance(dstType, (Pointer)value); s.conditionalAutoRead(); value = s; @@ -564,76 +599,74 @@ } return value; } - + private Object convertResult(Object value) { if (toNative != null) { value = toNative.toNative(value, new CallbackResultContext(callbackMethod)); } - if (value == null) + if (value == null) { return null; - Class cls = value.getClass(); + } + + Class cls = value.getClass(); if (Structure.class.isAssignableFrom(cls)) { if (Structure.ByValue.class.isAssignableFrom(cls)) { return value; } return ((Structure)value).getPointer(); - } - else if (cls == boolean.class || cls == Boolean.class) { - return Boolean.TRUE.equals(value) ? + } else if (cls == boolean.class || cls == Boolean.class) { + return Boolean.TRUE.equals(value) ? Function.INTEGER_TRUE : Function.INTEGER_FALSE; - } - else if (cls == String.class || cls == WString.class) { + } else if (cls == String.class || cls == WString.class) { return getNativeString(value, cls == WString.class); - } - else if (cls == String[].class || cls == WString.class) { + } else if (cls == String[].class || cls == WString.class) { StringArray sa = cls == String[].class ? new StringArray((String[])value, encoding) : new StringArray((WString[])value); // Delay GC until array itself is GC'd. allocations.put(value, sa); return sa; - } - else if (Callback.class.isAssignableFrom(cls)) { + } else if (Callback.class.isAssignableFrom(cls)) { return getFunctionPointer((Callback)value); } return value; } - public Class[] getParameterTypes() { + @Override + public Class[] getParameterTypes() { return callbackMethod.getParameterTypes(); } - public Class getReturnType() { + @Override + public Class getReturnType() { return callbackMethod.getReturnType(); } } - /** Provide invocation handling for an auto-generated Java interface proxy + /** Provide invocation handling for an auto-generated Java interface proxy * for a native function pointer. * Cf. Library.Handler */ private static class NativeFunctionHandler implements InvocationHandler { private final Function function; - private final Map options; - - public NativeFunctionHandler(Pointer address, int callingConvention, Map options) { - String encoding = (String)options.get(Library.OPTION_STRING_ENCODING); - this.function = new Function(address, callingConvention, encoding); + private final Map options; + + public NativeFunctionHandler(Pointer address, int callingConvention, Map options) { this.options = options; + this.function = new Function(address, callingConvention, (String) options.get(Library.OPTION_STRING_ENCODING)); } - + /** Chain invocation to the native function. */ + @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (Library.Handler.OBJECT_TOSTRING.equals(method)) { String str = "Proxy interface to " + function; Method m = (Method)options.get(Function.OPTION_INVOKING_METHOD); - Class cls = findCallbackClass(m.getDeclaringClass()); + Class cls = findCallbackClass(m.getDeclaringClass()); str += " (" + cls.getName() + ")"; return str; - } - else if (Library.Handler.OBJECT_HASHCODE.equals(method)) { - return new Integer(hashCode()); - } - else if (Library.Handler.OBJECT_EQUALS.equals(method)) { + } else if (Library.Handler.OBJECT_HASHCODE.equals(method)) { + return Integer.valueOf(hashCode()); + } else if (Library.Handler.OBJECT_EQUALS.equals(method)) { Object o = args[0]; if (o != null && Proxy.isProxyClass(o.getClass())) { return Function.valueOf(Proxy.getInvocationHandler(o) == this); @@ -645,7 +678,7 @@ } return function.invoke(method.getReturnType(), args, options); } - + public Pointer getPointer() { return function; } @@ -654,7 +687,7 @@ * Other types (String, WString, Structure, arrays, NativeMapped, * etc) are supported in the Java library. */ - private static boolean isAllowableNativeType(Class cls) { + private static boolean isAllowableNativeType(Class cls) { return cls == void.class || cls == Void.class || cls == boolean.class || cls == Boolean.class || cls == byte.class || cls == Byte.class @@ -664,11 +697,11 @@ || cls == long.class || cls == Long.class || cls == float.class || cls == Float.class || cls == double.class || cls == Double.class - || (Structure.ByValue.class.isAssignableFrom(cls) + || (Structure.ByValue.class.isAssignableFrom(cls) && Structure.class.isAssignableFrom(cls)) || Pointer.class.isAssignableFrom(cls); } - + private static Pointer getNativeString(Object value, boolean wide) { if (value != null) { NativeString ns = new NativeString(value.toString(), wide); diff -Nru libjna-java-4.2.2/src/com/sun/jna/CallbackResultContext.java libjna-java-4.4.0/src/com/sun/jna/CallbackResultContext.java --- libjna-java-4.2.2/src/com/sun/jna/CallbackResultContext.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/CallbackResultContext.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,3 +1,24 @@ +/* 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.lang.reflect.Method; diff -Nru libjna-java-4.2.2/src/com/sun/jna/CallbackThreadInitializer.java libjna-java-4.4.0/src/com/sun/jna/CallbackThreadInitializer.java --- libjna-java-4.2.2/src/com/sun/jna/CallbackThreadInitializer.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/CallbackThreadInitializer.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,15 +1,25 @@ -package com.sun.jna; /* Copyright (c) 2011 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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". */ /**

    This class provides for customization of the mapping of native threads * onto attached Java threads. Use @@ -30,6 +40,8 @@ * per callback, or you may subclass the initializer to provide different * initializer settings depending on the callback.

    */ +package com.sun.jna; + public class CallbackThreadInitializer { private boolean daemon; private boolean detach; diff -Nru libjna-java-4.2.2/src/com/sun/jna/DefaultTypeMapper.java libjna-java-4.4.0/src/com/sun/jna/DefaultTypeMapper.java --- libjna-java-4.2.2/src/com/sun/jna/DefaultTypeMapper.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/DefaultTypeMapper.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,94 +1,92 @@ /* Copyright (c) 2007 Wayne Meissner, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

    - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.ArrayList; -import java.util.Iterator; +import java.util.Collection; import java.util.List; /** Provide custom mappings to and from native types. The default lookup * checks classes corresponding to converters in the order added; if the * class to be converted is an instance of the converter's registered class, - * the converter will be used.

    - * Derived classes should install additional converters using + * the converter will be used.

    + * Derived classes should install additional converters using * {@link #addToNativeConverter} * and/or {@link #addFromNativeConverter} in the default constructor. Classes * for primitive types will automatically register for the corresponding - * Object type and vice versa (i.e. you don't have to register both + * Object type and vice versa (i.e. you don't have to register both * int.class and Integer.class). * If you want different mapping behavior than the default, simply override * {@link #getToNativeConverter} and {@link #getFromNativeConverter}. - * @see Library#OPTION_TYPE_MAPPER + * @see Library#OPTION_TYPE_MAPPER */ public class DefaultTypeMapper implements TypeMapper { private static class Entry { - public Class type; + public Class type; public Object converter; - public Entry(Class type, Object converter) { + public Entry(Class type, Object converter) { this.type = type; this.converter = converter; } } - private List toNativeConverters = new ArrayList(); - private List fromNativeConverters = new ArrayList(); - private Class getAltClass(Class cls) { + + private List toNativeConverters = new ArrayList(); + private List fromNativeConverters = new ArrayList(); + + private Class getAltClass(Class cls) { if (cls == Boolean.class) { return boolean.class; - } - else if (cls == boolean.class) { + } else if (cls == boolean.class) { return Boolean.class; - } - else if (cls == Byte.class) { + } else if (cls == Byte.class) { return byte.class; - } - else if (cls == byte.class) { + } else if (cls == byte.class) { return Byte.class; - } - else if (cls == Character.class) { + } else if (cls == Character.class) { return char.class; - } - else if (cls == char.class) { + } else if (cls == char.class) { return Character.class; - } - else if (cls == Short.class) { + } else if (cls == Short.class) { return short.class; - } - else if (cls == short.class) { + } else if (cls == short.class) { return Short.class; - } - else if (cls == Integer.class) { + } else if (cls == Integer.class) { return int.class; - } - else if (cls == int.class) { + } else if (cls == int.class) { return Integer.class; - } - else if (cls == Long.class) { + } else if (cls == Long.class) { return long.class; - } - else if (cls == long.class) { + } else if (cls == long.class) { return Long.class; - } - else if (cls == Float.class) { + } else if (cls == Float.class) { return float.class; - } - else if (cls == float.class) { + } else if (cls == float.class) { return Float.class; - } - else if (cls == Double.class) { + } else if (cls == Double.class) { return double.class; - } - else if (cls == double.class) { + } else if (cls == double.class) { return Double.class; } return null; @@ -100,56 +98,58 @@ * @param converter {@link ToNativeConverter} to transform an object of * the given Java class into its native-compatible form. */ - public void addToNativeConverter(Class cls, ToNativeConverter converter) { + public void addToNativeConverter(Class cls, ToNativeConverter converter) { toNativeConverters.add(new Entry(cls, converter)); - Class alt = getAltClass(cls); + Class alt = getAltClass(cls); if (alt != null) { toNativeConverters.add(new Entry(alt, converter)); } } - /** Add a {@link FromNativeConverter} to convert a native result type into the + /** + * Add a {@link FromNativeConverter} to convert a native result type into the * given Java type. Converters are checked for in the order added. + * * @param cls Java class for the Java representation of a native type. * @param converter {@link FromNativeConverter} to transform a * native-compatible type into its Java equivalent. */ - public void addFromNativeConverter(Class cls, FromNativeConverter converter) { + public void addFromNativeConverter(Class cls, FromNativeConverter converter) { fromNativeConverters.add(new Entry(cls, converter)); - Class alt = getAltClass(cls); + Class alt = getAltClass(cls); if (alt != null) { fromNativeConverters.add(new Entry(alt, converter)); } } - /** Add a {@link TypeConverter} to provide bidirectional mapping between - * a native and Java type. + + /** + * Add a {@link TypeConverter} to provide bidirectional mapping between + * a native and Java type. + * * @param cls Java class representation for a native type * @param converter {@link TypeConverter} to translate between native and * Java types. */ - public void addTypeConverter(Class cls, TypeConverter converter) { + public void addTypeConverter(Class cls, TypeConverter converter) { addFromNativeConverter(cls, converter); addToNativeConverter(cls, converter); } - - private Object lookupConverter(Class javaClass, List converters) { - for (Iterator i=converters.iterator();i.hasNext();) { - Entry entry = (Entry)i.next(); + + private Object lookupConverter(Class javaClass, Collection converters) { + for (Entry entry : converters) { if (entry.type.isAssignableFrom(javaClass)) { return entry.converter; } } return null; } - /* (non-Javadoc) - * @see com.sun.jna.TypeMapper#getFromNativeConverter(java.lang.Class) - */ - public FromNativeConverter getFromNativeConverter(Class javaType) { + + @Override + public FromNativeConverter getFromNativeConverter(Class javaType) { return (FromNativeConverter)lookupConverter(javaType, fromNativeConverters); } - /* (non-Javadoc) - * @see com.sun.jna.TypeMapper#getToNativeConverter(java.lang.Class) - */ - public ToNativeConverter getToNativeConverter(Class javaType) { + + @Override + public ToNativeConverter getToNativeConverter(Class javaType) { return (ToNativeConverter)lookupConverter(javaType, toNativeConverters); } } diff -Nru libjna-java-4.2.2/src/com/sun/jna/ELFAnalyser.java libjna-java-4.4.0/src/com/sun/jna/ELFAnalyser.java --- libjna-java-4.2.2/src/com/sun/jna/ELFAnalyser.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/ELFAnalyser.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,140 @@ + +package com.sun.jna; + +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.Arrays; + +/** + * Analyse an ELF file for platform specific attributes. + * + *

    Primary use-case: Detect whether the java binary is arm hardfloat or softfloat.

    + */ +class ELFAnalyser { + /** + * Generic ELF header + */ + private static final byte[] ELF_MAGIC = new byte[]{(byte) 0x7F, (byte) 'E', (byte) 'L', (byte) 'F'}; + /** + * e_flags mask if executable file conforms to hardware floating-point + * procedure-call standard (arm ABI version 5) + */ + private static final int EF_ARM_ABI_FLOAT_HARD = 0x00000400; + /** + * e_flags mask if executable file conforms to software floating-point + * procedure-call standard (arm ABI version 5) + */ + private static final int EF_ARM_ABI_FLOAT_SOFT = 0x00000200; + 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; + + public static ELFAnalyser analyse(String filename) throws IOException { + ELFAnalyser res = new ELFAnalyser(filename); + res.runDetection(); + return res; + } + + private final String filename; + private boolean ELF = false; + private boolean _64Bit = false; + private boolean bigEndian = false; + private boolean armHardFloat = false; + private boolean armSoftFloat = false; + private boolean arm = false; + + /** + * @return true if the parsed file was detected to be an ELF file + */ + public boolean isELF() { + return ELF; + } + + /** + * @return true if the parsed file was detected to be for a 64bit architecture + * and pointers are expected to be 8byte wide + */ + public boolean is64Bit() { + return _64Bit; + } + + /** + * @return true if the parsed file is detected to be big endian, false if + * the file is little endian + */ + public boolean isBigEndian() { + return bigEndian; + } + + /** + * @return filename of the parsed file + */ + public String getFilename() { + return filename; + } + + /** + * @return true if file was detected to conform to the hardware floating-point + * procedure-call standard + */ + public boolean isArmHardFloat() { + return armHardFloat; + } + + /** + * @return true if file was detected to conform to the software floating-point + * procedure-call standard + */ + public boolean isArmSoftFloat() { + return armSoftFloat; + } + + /** + * @return true if the parsed file was detected to be build for the arm + * architecture + */ + public boolean isArm() { + return arm; + } + + private ELFAnalyser(String filename) { + this.filename = filename; + } + + private void runDetection() throws IOException { + // run precheck - only of if the file at least hold an ELF header parsing + // runs further. + RandomAccessFile raf = new RandomAccessFile(filename, "r"); + if (raf.length() > 4) { + byte[] magic = new byte[4]; + raf.seek(0); + raf.read(magic); + if (Arrays.equals(magic, ELF_MAGIC)) { + ELF = true; + } + } + if (!ELF) { + return; + } + raf.seek(4); + // The total header size depends on the pointer size of the platform + // so before the header is loaded the pointer size has to be determined + byte sizeIndicator = raf.readByte(); + _64Bit = sizeIndicator == EI_CLASS_64BIT; + raf.seek(0); + ByteBuffer headerData = ByteBuffer.allocate(_64Bit ? 64 : 52); + raf.getChannel().read(headerData, 0); + bigEndian = headerData.get(5) == EI_DATA_BIG_ENDIAN; + headerData.order(bigEndian ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN); + + arm = headerData.get(0x12) == E_MACHINE_ARM; + + if(arm) { + int flags = headerData.getInt(_64Bit ? 0x30 : 0x24); + armSoftFloat = (flags & EF_ARM_ABI_FLOAT_SOFT) == EF_ARM_ABI_FLOAT_SOFT; + armHardFloat = (flags & EF_ARM_ABI_FLOAT_HARD) == EF_ARM_ABI_FLOAT_HARD; + } + } +} diff -Nru libjna-java-4.2.2/src/com/sun/jna/FromNativeContext.java libjna-java-4.4.0/src/com/sun/jna/FromNativeContext.java --- libjna-java-4.2.2/src/com/sun/jna/FromNativeContext.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/FromNativeContext.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,25 +1,36 @@ /* Copyright (c) 2007 Timothy Wall, 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; /** Provides context for converting a native value into a Java type. */ public class FromNativeContext { - private Class type; - FromNativeContext(Class javaType) { + private Class type; + FromNativeContext(Class javaType) { this.type = javaType; } /** The desired Java type of the result. */ - public Class getTargetType() { + public Class getTargetType() { return type; } } diff -Nru libjna-java-4.2.2/src/com/sun/jna/FromNativeConverter.java libjna-java-4.4.0/src/com/sun/jna/FromNativeConverter.java --- libjna-java-4.2.2/src/com/sun/jna/FromNativeConverter.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/FromNativeConverter.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Wayne Meissner, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

    - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; @@ -16,9 +27,9 @@ /** Define conversion from a native type to the appropriate Java type. */ public interface FromNativeConverter { /** Convert the given native object into its Java representation using - * the given context. + * the given context. */ Object fromNative(Object nativeValue, FromNativeContext context); /** Indicate the native type used by this converter. */ - Class nativeType(); + Class nativeType(); } diff -Nru libjna-java-4.2.2/src/com/sun/jna/Function.java libjna-java-4.4.0/src/com/sun/jna/Function.java --- libjna-java-4.2.2/src/com/sun/jna/Function.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/Function.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,12 +1,23 @@ -/* This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

    - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. +/* 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; @@ -15,13 +26,13 @@ import java.util.Map; /** - *

    An abstraction for a native function pointer. An instance of - * Function represents a pointer to some native function. + *

    An abstraction for a native function pointer. An instance of + * Function represents a pointer to some native function. * {@link #invoke(Class,Object[],Map)} is the primary means to call * the function.

    * * Function call behavior may be modified by passing one of the following call - * flags: + * flags: *
      *
    • {@link Function#C_CONVENTION} Use C calling convention (default) *
    • {@link Function#ALT_CONVENTION} Use alternate calling convention (e.g. stdcall) @@ -47,7 +58,7 @@ */ void read(); } - + /** Maximum number of arguments supported by a JNA function call. */ public static final int MAX_NARGS = 256; @@ -59,15 +70,17 @@ private static final int MASK_CC = 0x3F; /** Whether to throw an exception if last error is non-zero after call. */ public static final int THROW_LAST_ERROR = 0x40; + /** Mask for number of fixed args (1-3) for varargs calls. */ + public static final int USE_VARARGS = 0x180; - static final Integer INTEGER_TRUE = new Integer(-1); - static final Integer INTEGER_FALSE = new Integer(0); + static final Integer INTEGER_TRUE = Integer.valueOf(-1); + static final Integer INTEGER_FALSE = Integer.valueOf(0); - /** - * Obtain a Function representing a native + /** + * Obtain a Function representing a native * function that follows the standard "C" calling convention. - * - *

      The allocated instance represents a pointer to the named native + * + *

      The allocated instance represents a pointer to the named native * function from the named library, called with the standard "C" calling * convention. * @@ -81,12 +94,12 @@ public static Function getFunction(String libraryName, String functionName) { return NativeLibrary.getInstance(libraryName).getFunction(functionName); } - + /** - * Obtain a Function representing a native + * Obtain a Function representing a native * function. - * - *

      The allocated instance represents a pointer to the named native + * + *

      The allocated instance represents a pointer to the named native * function from the named library. * * @param libraryName @@ -95,19 +108,19 @@ * Name of the native function to be linked with * @param callFlags * Function call flags - * + * * @throws UnsatisfiedLinkError if the library is not found or * the given function name is not found within the library. */ public static Function getFunction(String libraryName, String functionName, int callFlags) { return NativeLibrary.getInstance(libraryName).getFunction(functionName, callFlags, null); } - + /** - * Obtain a Function representing a native + * Obtain a Function representing a native * function. - * - *

      The allocated instance represents a pointer to the named native + * + *

      The allocated instance represents a pointer to the named native * function from the named library. * * @param libraryName @@ -119,36 +132,36 @@ * @param encoding * Encoding to use for conversion between Java and native * strings. - * + * * @throws UnsatisfiedLinkError if the library is not found or * the given function name is not found within the library. */ public static Function getFunction(String libraryName, String functionName, int callFlags, String encoding) { return NativeLibrary.getInstance(libraryName).getFunction(functionName, callFlags, encoding); } - + /** - * Obtain a Function representing a native + * Obtain a Function representing a native * function pointer. In general, this function should be used by dynamic * languages; Java code should allow JNA to bind to a specific Callback * interface instead by defining a return type or Structure field type. - * - *

      The allocated instance represents a pointer to the native + * + *

      The allocated instance represents a pointer to the native * function pointer. * * @param p Native function pointer */ public static Function getFunction(Pointer p) { - return getFunction(p, 0); + return getFunction(p, 0, null); } /** - * Obtain a Function representing a native + * Obtain a Function representing a native * function pointer. In general, this function should be used by dynamic * languages; Java code should allow JNA to bind to a specific Callback - * interface instead by defining a return type or Structure field type. - * - *

      The allocated instance represents a pointer to the native + * interface instead by defining a return type or Structure field type. + * + *

      The allocated instance represents a pointer to the native * function pointer. * * @param p @@ -157,7 +170,28 @@ * Function call flags */ public static Function getFunction(Pointer p, int callFlags) { - return new Function(p, callFlags, null); + return getFunction(p, callFlags, null); + } + + /** + * Obtain a Function representing a native + * function pointer. In general, this function should be used by dynamic + * languages; Java code should allow JNA to bind to a specific Callback + * interface instead by defining a return type or Structure field type. + * + *

      The allocated instance represents a pointer to the native + * function pointer. + * + * @param p + * Native function pointer + * @param callFlags + * Function call flags + * @param encoding + * Encoding to use for conversion between Java and native + * strings. + */ + public static Function getFunction(Pointer p, int callFlags, String encoding) { + return new Function(p, callFlags, encoding); } // Keep a reference to the NativeLibrary so it does not get garbage @@ -166,7 +200,7 @@ private final String functionName; final String encoding; final int callFlags; - final Map options; + final Map options; /** For internal JNA use. */ static final String OPTION_INVOKING_METHOD = "invoking-method"; @@ -175,11 +209,11 @@ private static final VarArgsChecker IS_VARARGS = VarArgsChecker.create(); /** - * Create a new Function that is linked with a native + * Create a new Function that is linked with a native * function that follows the given calling convention. - * - *

      The allocated instance represents a pointer to the named native - * function from the supplied library, called with the given calling + * + *

      The allocated instance represents a pointer to the named native + * function from the supplied library, called with the given calling * convention. * * @param library @@ -195,34 +229,33 @@ */ Function(NativeLibrary library, String functionName, int callFlags, String encoding) { checkCallingConvention(callFlags & MASK_CC); - if (functionName == null) + if (functionName == null) { throw new NullPointerException("Function name must not be null"); + } this.library = library; this.functionName = functionName; this.callFlags = callFlags; this.options = library.options; - this.encoding = encoding != null - ? encoding : Native.getDefaultStringEncoding(); + this.encoding = encoding != null ? encoding : Native.getDefaultStringEncoding(); try { this.peer = library.getSymbolAddress(functionName); - } - catch(UnsatisfiedLinkError e) { - throw new UnsatisfiedLinkError("Error looking up function '" - + functionName + "': " + } catch(UnsatisfiedLinkError e) { + throw new UnsatisfiedLinkError("Error looking up function '" + + functionName + "': " + e.getMessage()); } } - + /** - * Create a new Function that is linked with a native + * Create a new Function that is linked with a native * function that follows the given calling convention. - * - *

      The allocated instance represents a pointer to the given - * function address, called with the given calling + * + *

      The allocated instance represents a pointer to the given + * function address, called with the given calling * convention. * * @param functionAddress - * Address of the native function + * Address of the native function * @param callFlags * Function call flags * @param encoding @@ -241,12 +274,12 @@ this.encoding = encoding != null ? encoding : Native.getDefaultStringEncoding(); } - + private void checkCallingConvention(int convention) throws IllegalArgumentException { // TODO: perform per-platform calling convention checks if ((convention & MASK_CC) != convention) { - throw new IllegalArgumentException("Unrecognized calling convention: " + throw new IllegalArgumentException("Unrecognized calling convention: " + convention); } } @@ -262,16 +295,16 @@ /** Invoke the native function with the given arguments, returning the * native result as an Object. */ - public Object invoke(Class returnType, Object[] inArgs) { + public Object invoke(Class returnType, Object[] inArgs) { return invoke(returnType, inArgs, this.options); - } - + } + /** Invoke the native function with the given arguments, returning the * native result as an Object. */ - public Object invoke(Class returnType, Object[] inArgs, Map options) { + public Object invoke(Class returnType, Object[] inArgs, Map options) { Method invokingMethod = (Method)options.get(OPTION_INVOKING_METHOD); - Class[] paramTypes = invokingMethod != null ? invokingMethod.getParameterTypes() : null; + Class[] paramTypes = invokingMethod != null ? invokingMethod.getParameterTypes() : null; return invoke(invokingMethod, paramTypes, returnType, inArgs, options); } @@ -280,7 +313,7 @@ * types are already at hand. When calling {@link Function#invoke(Class, Object[], Map)}, * the method has to be in the options under key {@link Function#OPTION_INVOKING_METHOD}. */ - Object invoke(Method invokingMethod, Class[] paramTypes, Class returnType, Object[] inArgs, Map options) { + Object invoke(Method invokingMethod, Class[] paramTypes, Class returnType, Object[] inArgs, Map options) { // Clone the argument array to obtain a scratch space for modified // types/values Object[] args = { }; @@ -292,36 +325,33 @@ System.arraycopy(inArgs, 0, args, 0, args.length); } - TypeMapper mapper = - (TypeMapper)options.get(Library.OPTION_TYPE_MAPPER); + TypeMapper mapper = (TypeMapper)options.get(Library.OPTION_TYPE_MAPPER); boolean allowObjects = Boolean.TRUE.equals(options.get(Library.OPTION_ALLOW_OBJECTS)); boolean isVarArgs = args.length > 0 && invokingMethod != null ? isVarArgs(invokingMethod) : false; + int fixedArgs = args.length > 0 && invokingMethod != null ? fixedArgs(invokingMethod) : 0; for (int i=0; i < args.length; i++) { - Class paramType = invokingMethod != null + Class paramType = invokingMethod != null ? (isVarArgs && i >= paramTypes.length-1 ? paramTypes[paramTypes.length-1].getComponentType() : paramTypes[i]) : null; - args[i] = convertArgument(args, i, invokingMethod, - mapper, allowObjects, paramType); + args[i] = convertArgument(args, i, invokingMethod, mapper, allowObjects, paramType); } - - Class nativeReturnType = returnType; + + Class nativeReturnType = returnType; FromNativeConverter resultConverter = null; if (NativeMapped.class.isAssignableFrom(returnType)) { NativeMappedConverter tc = NativeMappedConverter.getInstance(returnType); resultConverter = tc; nativeReturnType = tc.nativeType(); - } - else if (mapper != null) { + } else if (mapper != null) { resultConverter = mapper.getFromNativeConverter(returnType); if (resultConverter != null) { nativeReturnType = resultConverter.nativeType(); } } - Object result = invoke(args, nativeReturnType, allowObjects); - + Object result = invoke(args, nativeReturnType, allowObjects, fixedArgs); // Convert the result to a custom value/type if appropriate if (resultConverter != null) { FromNativeContext context; @@ -343,13 +373,12 @@ if (!(inArg instanceof Structure.ByValue)) { ((Structure)inArg).autoRead(); } - } - else if (args[i] instanceof PostCallRead) { + } else if (args[i] instanceof PostCallRead) { ((PostCallRead)args[i]).read(); if (args[i] instanceof PointerArray) { PointerArray array = (PointerArray)args[i]; if (Structure.ByReference[].class.isAssignableFrom(inArg.getClass())) { - Class type = inArg.getClass().getComponentType(); + Class type = inArg.getClass().getComponentType(); Structure[] ss = (Structure[])inArg; for (int si=0;si < ss.length;si++) { Pointer p = array.getPointer(Pointer.SIZE * si); @@ -357,68 +386,60 @@ } } } - } - else if (Structure[].class.isAssignableFrom(inArg.getClass())) { + } else if (Structure[].class.isAssignableFrom(inArg.getClass())) { Structure.autoRead((Structure[])inArg); } } } - + return result; } - /** @see NativeLibrary#NativeLibrary(String,String,long,Map) implementation */ - Object invoke(Object[] args, Class returnType, boolean allowObjects) { + /* @see NativeLibrary#NativeLibrary(String,String,long,Map) implementation */ + Object invoke(Object[] args, Class returnType, boolean allowObjects) { + return invoke(args, returnType, allowObjects, 0); + } + + /* @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); if (returnType == null || returnType==void.class || returnType==Void.class) { - Native.invokeVoid(peer, callFlags, args); + Native.invokeVoid(this, this.peer, callFlags, args); result = null; - } - else if (returnType==boolean.class || returnType==Boolean.class) { - result = valueOf(Native.invokeInt(peer, callFlags, args) != 0); - } - else if (returnType==byte.class || returnType==Byte.class) { - result = new Byte((byte)Native.invokeInt(peer, callFlags, args)); - } - else if (returnType==short.class || returnType==Short.class) { - result = new Short((short)Native.invokeInt(peer, callFlags, args)); - } - else if (returnType==char.class || returnType==Character.class) { - result = new Character((char)Native.invokeInt(peer, callFlags, args)); - } - else if (returnType==int.class || returnType==Integer.class) { - result = new Integer(Native.invokeInt(peer, callFlags, args)); - } - else if (returnType==long.class || returnType==Long.class) { - result = new Long(Native.invokeLong(peer, callFlags, args)); - } - else if (returnType==float.class || returnType==Float.class) { - result = new Float(Native.invokeFloat(peer, callFlags, args)); - } - else if (returnType==double.class || returnType==Double.class) { - result = new Double(Native.invokeDouble(peer, callFlags, args)); - } - else if (returnType==String.class) { + } else if (returnType==boolean.class || returnType==Boolean.class) { + result = valueOf(Native.invokeInt(this, this.peer, callFlags, args) != 0); + } else if (returnType==byte.class || returnType==Byte.class) { + result = Byte.valueOf((byte)Native.invokeInt(this, this.peer, callFlags, args)); + } else if (returnType==short.class || returnType==Short.class) { + result = Short.valueOf((short)Native.invokeInt(this, this.peer, callFlags, args)); + } else if (returnType==char.class || returnType==Character.class) { + result = Character.valueOf((char)Native.invokeInt(this, this.peer, callFlags, args)); + } else if (returnType==int.class || returnType==Integer.class) { + result = Integer.valueOf(Native.invokeInt(this, this.peer, callFlags, args)); + } else if (returnType==long.class || returnType==Long.class) { + result = Long.valueOf(Native.invokeLong(this, this.peer, callFlags, args)); + } else if (returnType==float.class || returnType==Float.class) { + result = Float.valueOf(Native.invokeFloat(this, this.peer, callFlags, args)); + } else if (returnType==double.class || returnType==Double.class) { + result = Double.valueOf(Native.invokeDouble(this, this.peer, callFlags, args)); + } else if (returnType==String.class) { result = invokeString(callFlags, args, false); - } - else if (returnType==WString.class) { + } else if (returnType==WString.class) { String s = invokeString(callFlags, args, true); if (s != null) { result = new WString(s); } - } - else if (Pointer.class.isAssignableFrom(returnType)) { + } else if (Pointer.class.isAssignableFrom(returnType)) { return invokePointer(callFlags, args); - } - else if (Structure.class.isAssignableFrom(returnType)) { + } else if (Structure.class.isAssignableFrom(returnType)) { if (Structure.ByValue.class.isAssignableFrom(returnType)) { - Structure s = - Native.invokeStructure(peer, callFlags, args, + Structure s = + Native.invokeStructure(this, this.peer, callFlags, args, Structure.newInstance(returnType)); s.autoRead(); result = s; - } - else { + } else { result = invokePointer(callFlags, args); if (result != null) { Structure s = Structure.newInstance(returnType, (Pointer)result); @@ -426,20 +447,17 @@ result = s; } } - } - else if (Callback.class.isAssignableFrom(returnType)) { + } else if (Callback.class.isAssignableFrom(returnType)) { result = invokePointer(callFlags, args); if (result != null) { result = CallbackReference.getCallback(returnType, (Pointer)result); } - } - else if (returnType==String[].class) { + } else if (returnType==String[].class) { Pointer p = invokePointer(callFlags, args); if (p != null) { result = p.getStringArray(0, encoding); } - } - else if (returnType==WString[].class) { + } else if (returnType==WString[].class) { Pointer p = invokePointer(callFlags, args); if (p != null) { String[] arr = p.getWideStringArray(0); @@ -449,46 +467,40 @@ } result = warr; } - } - else if (returnType==Pointer[].class) { + } else if (returnType==Pointer[].class) { Pointer p = invokePointer(callFlags, args); if (p != null) { result = p.getPointerArray(0); } - } - else if (allowObjects) { - result = Native.invokeObject(peer, callFlags, args); + } else if (allowObjects) { + result = Native.invokeObject(this, this.peer, callFlags, args); if (result != null && !returnType.isAssignableFrom(result.getClass())) { throw new ClassCastException("Return type " + returnType + " does not match result " + result.getClass()); } - } - else { - throw new IllegalArgumentException("Unsupported return type " - + returnType - + " in function " + getName()); + } else { + throw new IllegalArgumentException("Unsupported return type " + returnType + " in function " + getName()); } return result; } - + private Pointer invokePointer(int callFlags, Object[] args) { - long ptr = Native.invokePointer(peer, callFlags, args); + long ptr = Native.invokePointer(this, this.peer, callFlags, args); return ptr == 0 ? null : new Pointer(ptr); } private Object convertArgument(Object[] args, int index, Method invokingMethod, TypeMapper mapper, - boolean allowObjects, Class expectedType) { + boolean allowObjects, Class expectedType) { Object arg = args[index]; if (arg != null) { - Class type = arg.getClass(); + Class type = arg.getClass(); ToNativeConverter converter = null; if (NativeMapped.class.isAssignableFrom(type)) { converter = NativeMappedConverter.getInstance(type); - } - else if (mapper != null) { + } else if (mapper != null) { converter = mapper.getToNativeConverter(type); } if (converter != null) { @@ -502,31 +514,30 @@ arg = converter.toNative(arg, context); } } - if (arg == null || isPrimitiveArray(arg.getClass())) { + if (arg == null || isPrimitiveArray(arg.getClass())) { return arg; } - Class argClass = arg.getClass(); - // Convert Structures to native pointers + + Class argClass = arg.getClass(); + // Convert Structures to native pointers if (arg instanceof Structure) { Structure struct = (Structure)arg; struct.autoWrite(); if (struct instanceof Structure.ByValue) { // Double-check against the method signature, if available - Class ptype = struct.getClass(); + Class ptype = struct.getClass(); if (invokingMethod != null) { - Class[] ptypes = invokingMethod.getParameterTypes(); + Class[] ptypes = invokingMethod.getParameterTypes(); if (IS_VARARGS.isVarArgs(invokingMethod)) { if (index < ptypes.length-1) { ptype = ptypes[index]; - } - else { - Class etype = ptypes[ptypes.length-1].getComponentType(); + } else { + Class etype = ptypes[ptypes.length-1].getComponentType(); if (etype != Object.class) { ptype = etype; } } - } - else { + } else { ptype = ptypes[index]; } } @@ -535,44 +546,35 @@ } } return struct.getPointer(); - } - // Convert Callback to Pointer - else if (arg instanceof Callback) { + } else if (arg instanceof Callback) { + // Convert Callback to Pointer return CallbackReference.getFunctionPointer((Callback)arg); - } - // String arguments are converted to native pointers here rather - // than in native code so that the values will be valid until - // this method returns. - // Convert String to native pointer (const) - else if (arg instanceof String) { + } else if (arg instanceof String) { + // String arguments are converted to native pointers here rather + // 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(); - } - // Convert WString to native pointer (const) - else if (arg instanceof WString) { + } else if (arg instanceof WString) { + // Convert WString to native pointer (const) return new NativeString(arg.toString(), true).getPointer(); - } - // Default conversion of boolean to int; if you want something - // different, use a ToNativeConverter - else if (arg instanceof Boolean) { + } else if (arg instanceof Boolean) { + // Default conversion of boolean to int; if you want something + // different, use a ToNativeConverter return Boolean.TRUE.equals(arg) ? INTEGER_TRUE : INTEGER_FALSE; - } - else if (String[].class == argClass) { + } else if (String[].class == argClass) { return new StringArray((String[])arg, encoding); - } - else if (WString[].class == argClass) { + } else if (WString[].class == argClass) { return new StringArray((WString[])arg); - } - else if (Pointer[].class == argClass) { + } else if (Pointer[].class == argClass) { return new PointerArray((Pointer[])arg); - } - else if (NativeMapped[].class.isAssignableFrom(argClass)) { + } else if (NativeMapped[].class.isAssignableFrom(argClass)) { return new NativeMappedArray((NativeMapped[])arg); - } - else if (Structure[].class.isAssignableFrom(argClass)) { + } else if (Structure[].class.isAssignableFrom(argClass)) { // If the signature is Structure[], disallow // Structure.ByReference[] and Structure.ByReference elements Structure[] ss = (Structure[])arg; - Class type = argClass.getComponentType(); + Class type = argClass.getComponentType(); boolean byRef = Structure.ByReference.class.isAssignableFrom(type); if (expectedType != null) { if (!Structure.ByReference[].class.isAssignableFrom(expectedType)) { @@ -599,27 +601,21 @@ pointers[i] = ss[i] != null ? ss[i].getPointer() : null; } return new PointerArray(pointers); - } - else if (ss.length == 0) { + } else if (ss.length == 0) { throw new IllegalArgumentException("Structure array must have non-zero length"); - } - else if (ss[0] == null) { + } else if (ss[0] == null) { Structure.newInstance(type).toArray(ss); return ss[0].getPointer(); - } - else { + } else { Structure.autoWrite(ss); return ss[0].getPointer(); } - } - else if (argClass.isArray()){ - throw new IllegalArgumentException("Unsupported array argument type: " + } else if (argClass.isArray()){ + throw new IllegalArgumentException("Unsupported array argument type: " + argClass.getComponentType()); - } - else if (allowObjects) { + } else if (allowObjects) { return arg; - } - else if (!Native.isSupportedNativeType(arg.getClass())) { + } else if (!Native.isSupportedNativeType(arg.getClass())) { throw new IllegalArgumentException("Unsupported argument type " + arg.getClass().getName() + " at parameter " + index @@ -628,11 +624,11 @@ return arg; } - private boolean isPrimitiveArray(Class argClass) { - return argClass.isArray() + private boolean isPrimitiveArray(Class argClass) { + return argClass.isArray() && argClass.getComponentType().isPrimitive(); } - + /** * Call the native function being represented by this object * @@ -669,6 +665,7 @@ } /** Provide a human-readable representation of this object. */ + @Override public String toString() { if (library != null) { return "native function " + functionName + "(" + library.getName() @@ -684,13 +681,13 @@ return invoke(Object.class, args); } - /** Convenience method for + /** Convenience method for * {@link #invoke(Class,Object[]) invoke(Pointer.class, args)}. */ public Pointer invokePointer(Object[] args) { return (Pointer)invoke(Pointer.class, args); } - + /** Convenience method for * {@link #invoke(Class,Object[]) invoke(String.class, args)} * or {@link #invoke(Class,Object[]) invoke(WString.class, args)} @@ -703,40 +700,41 @@ return o != null ? o.toString() : null; } - /** Convenience method for + /** Convenience method for * {@link #invoke(Class,Object[]) invoke(Integer.class, args)}. */ public int invokeInt(Object[] args) { return ((Integer)invoke(Integer.class, args)).intValue(); } - /** Convenience method for + /** Convenience method for * {@link #invoke(Class,Object[]) invoke(Long.class, args)}. */ public long invokeLong(Object[] args) { return ((Long)invoke(Long.class, args)).longValue(); } - /** Convenience method for + /** Convenience method for * {@link #invoke(Class,Object[]) invoke(Float.class, args)}. */ public float invokeFloat(Object[] args) { return ((Float)invoke(Float.class, args)).floatValue(); } - /** Convenience method for + /** Convenience method for * {@link #invoke(Class,Object[]) invoke(Double.class, args)}. */ public double invokeDouble(Object[] args) { return ((Double)invoke(Double.class, args)).doubleValue(); } - /** Convenience method for + /** Convenience method for * {@link #invoke(Class,Object[]) invoke(Void.class, args)}. */ public void invokeVoid(Object[] args) { invoke(Void.class, args); } - + /** Two function pointers are equal if they share the same peer address * and calling convention. */ + @Override public boolean equals(Object o) { if (o == this) return true; if (o == null) return false; @@ -752,28 +750,35 @@ /** Provide a unique hash code for {@link Function}s which are equivalent. */ + @Override public int hashCode() { return callFlags + options.hashCode() + super.hashCode(); } - /** Concatenate varargs with normal args to obtain a simple argument - * array. + /** Concatenate varargs with normal args to obtain a simple argument + * array. */ static Object[] concatenateVarArgs(Object[] inArgs) { // If the final argument is an array of something other than - // primitives, Structure, or String, treat it as varargs and + // primitives, Structure, or String, treat it as varargs and // concatenate the previous arguments with the varargs elements. if (inArgs != null && inArgs.length > 0) { Object lastArg = inArgs[inArgs.length-1]; - Class argType = lastArg != null ? lastArg.getClass() : null; + Class argType = lastArg != null ? lastArg.getClass() : null; if (argType != null && argType.isArray()) { Object[] varArgs = (Object[])lastArg; + // Promote float varargs to double (https://github.com/java-native-access/jna/issues/463). + for (int i=0; i < varArgs.length; i++) { + if (varArgs[i] instanceof Float) { + varArgs[i] = (double)(Float)varArgs[i]; + } + } Object[] fullArgs = new Object[inArgs.length+varArgs.length]; System.arraycopy(inArgs, 0, fullArgs, 0, inArgs.length-1); System.arraycopy(varArgs, 0, fullArgs, inArgs.length-1, varArgs.length); // For convenience, always append a NULL argument to the end // of varargs, whether the called API requires it or not. If - // it is not needed, it will be ignored, but if it *is* + // it is not needed, it will be ignored, but if it *is* // required, it avoids forcing the Java client to always // explicitly add it. fullArgs[fullArgs.length-1] = null; @@ -782,12 +787,17 @@ } return inArgs; } - + /** Varargs are only supported on 1.5+. */ static boolean isVarArgs(Method m) { return IS_VARARGS.isVarArgs(m); } - + + /** Varargs are only supported on 1.5+. */ + static int fixedArgs(Method m) { + return IS_VARARGS.fixedArgs(m); + } + private static class NativeMappedArray extends Memory implements PostCallRead { private final NativeMapped[] original; public NativeMappedArray(NativeMapped[] arg) { @@ -795,6 +805,7 @@ this.original = arg; setValue(0, original, original.getClass()); } + @Override public void read() { getValue(0, original.getClass(), original); } @@ -810,11 +821,12 @@ } setPointer(Pointer.SIZE*arg.length, null); } + @Override public void read() { read(0, original, 0, original.length); } } - + /** Implementation of Boolean.valueOf for older VMs. */ static Boolean valueOf(boolean b) { return b ? Boolean.TRUE : Boolean.FALSE; diff -Nru libjna-java-4.2.2/src/com/sun/jna/FunctionMapper.java libjna-java-4.4.0/src/com/sun/jna/FunctionMapper.java --- libjna-java-4.2.2/src/com/sun/jna/FunctionMapper.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/FunctionMapper.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; diff -Nru libjna-java-4.2.2/src/com/sun/jna/FunctionParameterContext.java libjna-java-4.4.0/src/com/sun/jna/FunctionParameterContext.java --- libjna-java-4.2.2/src/com/sun/jna/FunctionParameterContext.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/FunctionParameterContext.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Wayne Meissner, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; diff -Nru libjna-java-4.2.2/src/com/sun/jna/FunctionResultContext.java libjna-java-4.4.0/src/com/sun/jna/FunctionResultContext.java --- libjna-java-4.2.2/src/com/sun/jna/FunctionResultContext.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/FunctionResultContext.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,29 +1,46 @@ /* Copyright (c) 2007 Timothy Wall, 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; /** Provide result conversion context for a function call. */ public class FunctionResultContext extends FromNativeContext { - private Function function; private Object[] args; - FunctionResultContext(Class resultClass, Function function, Object[] args) { + + FunctionResultContext(Class resultClass, Function function, Object[] args) { super(resultClass); this.function = function; this.args = args; } - /** Get the function that was invoked. */ - public Function getFunction() { return function; } - /** Get the arguments used in this function call. */ - public Object[] getArguments() { return args; } + + /** @return The {@link Function} that was invoked. */ + public Function getFunction() { + return function; + } + + /** @return The arguments used in this function call. */ + public Object[] getArguments() { + return args; + } } diff -Nru libjna-java-4.2.2/src/com/sun/jna/IntegerType.java libjna-java-4.4.0/src/com/sun/jna/IntegerType.java --- libjna-java-4.2.2/src/com/sun/jna/IntegerType.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/IntegerType.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Wayne Meissner, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

      - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; @@ -26,6 +37,7 @@ * @author twalljava@java.net */ public abstract class IntegerType extends Number implements NativeMapped { + private static final long serialVersionUID = 1L; private int size; private Number number; @@ -65,20 +77,20 @@ case 1: if (unsigned) this.value = value & 0xFFL; truncated = (byte) value; - this.number = new Byte((byte) value); + this.number = Byte.valueOf((byte) value); break; case 2: if (unsigned) this.value = value & 0xFFFFL; truncated = (short) value; - this.number = new Short((short) value); + this.number = Short.valueOf((short) value); break; case 4: if (unsigned) this.value = value & 0xFFFFFFFFL; truncated = (int) value; - this.number = new Integer((int) value); + this.number = Integer.valueOf((int) value); break; case 8: - this.number = new Long(value); + this.number = Long.valueOf(value); break; default: throw new IllegalArgumentException("Unsupported size: " + size); @@ -120,7 +132,7 @@ } @Override - public Class nativeType() { + public Class nativeType() { return number.getClass(); } diff -Nru libjna-java-4.2.2/src/com/sun/jna/InvocationMapper.java libjna-java-4.4.0/src/com/sun/jna/InvocationMapper.java --- libjna-java-4.2.2/src/com/sun/jna/InvocationMapper.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/InvocationMapper.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,3 +1,25 @@ +/** + * 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.lang.reflect.InvocationHandler; @@ -26,7 +48,7 @@ * public Object invoke(Object proxy, Method method, Object[] args) { * Object[] newArgs = new Object[args.length+1]; * System.arraycopy(args, 0, newArgs, 1, args.length); - * newArgs[0] = new Integer(3); // _xstat version + * newArgs[0] = Integer.valueOf(3); // _xstat version * return f.invoke(newArgs); * } * }; diff -Nru libjna-java-4.2.2/src/com/sun/jna/LastErrorException.java libjna-java-4.4.0/src/com/sun/jna/LastErrorException.java --- libjna-java-4.2.2/src/com/sun/jna/LastErrorException.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/LastErrorException.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,26 +1,38 @@ /* Copyright (c) 2009 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

      - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; -/** +/** * Exception representing a non-zero error code returned in either - * errno + * errno * or GetLastError(). */ public class LastErrorException extends RuntimeException { - + private static final long serialVersionUID = 1L; + private int errorCode; - + private static String formatMessage(int code) { return Platform.isWindows() ? "GetLastError() returned " + code @@ -30,12 +42,18 @@ private static String parseMessage(String m) { try { return formatMessage(Integer.parseInt(m)); - } - catch(NumberFormatException e) { + } catch(NumberFormatException e) { return m; } } - + + /** + * @return The reported error code + */ + public int getErrorCode() { + return errorCode; + } + public LastErrorException(String msg) { super(parseMessage(msg.trim())); try { @@ -43,23 +61,17 @@ msg = msg.substring(1, msg.indexOf("]")); } this.errorCode = Integer.parseInt(msg); - } - catch(NumberFormatException e) { + } catch(NumberFormatException e) { this.errorCode = -1; } } - - /** - * Returns the error code of the error. - * @return - * Error code. - */ - public int getErrorCode() { - return errorCode; - } - + public LastErrorException(int code) { - super(formatMessage(code)); + this(code, formatMessage(code)); + } + + protected LastErrorException(int code, String msg) { + super(msg); this.errorCode = code; } } \ No newline at end of file diff -Nru libjna-java-4.2.2/src/com/sun/jna/Library.java libjna-java-4.4.0/src/com/sun/jna/Library.java --- libjna-java-4.2.2/src/com/sun/jna/Library.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/Library.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,12 +1,23 @@ -/* This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

      - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. +/* 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; @@ -26,39 +37,39 @@ * *

      * By convention, method names are identical to the native names, although you - * can map java names to different native names by providing a + * can map java names to different native names by providing a * {@link FunctionMapper} as a value for key {@link #OPTION_FUNCTION_MAPPER} * in the options map passed to the * {@link Native#loadLibrary(String, Class, Map)} call. *

      - * Although the names for structures and structure fields may be chosen - * arbitrarily, they should correspond as closely as possible to the native + * Although the names for structures and structure fields may be chosen + * arbitrarily, they should correspond as closely as possible to the native * definitions. The same is true for parameter names. *

      * This interface supports multiple, concurrent invocations of any library * methods on the Java side. Check your library documentation for its * multi-threading requirements on the native side. If a library is not safe - * for simultaneous multi-threaded access, consider using - * {@link Native#synchronizedLibrary} to prevent simultaneous multi-threaded - * access to the native code. + * for simultaneous multi-threaded access, consider using + * {@link Native#synchronizedLibrary} to prevent simultaneous multi-threaded + * access to the native code. *

      * Optional fields
      * Interface options will be automatically propagated to structures defined - * within the library provided a call to + * within the library provided a call to * {@link Native#loadLibrary(String,Class,Map)} is made prior to instantiating * any of those structures. One common way of ensuring this is to declare - * an INSTANCE field in the interface which holds the + * an INSTANCE field in the interface which holds the * loadLibrary result. *

      * OPTIONS (an instance of {@link Map}), * TYPE_MAPPER (an instance of {@link TypeMapper}), - * STRUCTURE_ALIGNMENT (one of the alignment types defined in + * STRUCTURE_ALIGNMENT (one of the alignment types defined in * {@link Structure}), and STRING_ENCODING (a {@link String}) may also * be defined. If no instance of the interface has been instantiated, these * fields will be used to determine customization settings for structures and - * methods defined within the interface. + * methods defined within the interface. *

      - * + * * @author Todd Fast, todd.fast@sun.com * @author Timothy Wall, twalljava@dev.java.net */ @@ -70,7 +81,7 @@ /** Option key for an {@link InvocationMapper} for the library. */ String OPTION_INVOCATION_MAPPER = "invocation-mapper"; /** Option key for structure alignment type ({@link Integer}), which should - * be one of the predefined alignment types in {@link Structure}. + * be one of the predefined alignment types in {@link Structure}. */ String OPTION_STRUCTURE_ALIGNMENT = "structure-alignment"; /**

      Option key for per-library String encoding. This affects conversions @@ -102,110 +113,107 @@ String OPTION_CLASSLOADER = "classloader"; static class Handler implements InvocationHandler { - + static final Method OBJECT_TOSTRING; static final Method OBJECT_HASHCODE; static final Method OBJECT_EQUALS; - + static { try { - OBJECT_TOSTRING = Object.class.getMethod("toString", new Class[0]); - OBJECT_HASHCODE= Object.class.getMethod("hashCode", new Class[0]); - OBJECT_EQUALS = Object.class.getMethod("equals", new Class[] { Object.class }); - } - catch (Exception e) { + OBJECT_TOSTRING = Object.class.getMethod("toString"); + OBJECT_HASHCODE= Object.class.getMethod("hashCode"); + OBJECT_EQUALS = Object.class.getMethod("equals", Object.class); + } catch (Exception e) { throw new Error("Error retrieving Object.toString() method"); } } + /** + * FunctionInfo has to be immutable to to make the object visible + * to other threads fully initialized. This is a prerequisite for + * using the class in the double checked locking scenario of {@link Handler#invoke(Object, Method, Object[])} + */ + private static final class FunctionInfo { + final InvocationHandler handler; + final Function function; + final boolean isVarArgs; + final Map options; + final Class[] parameterTypes; + + FunctionInfo(InvocationHandler handler, Function function, Class[] parameterTypes, boolean isVarArgs, Map options) { + this.handler = handler; + this.function = function; + this.isVarArgs = isVarArgs; + this.options = options; + this.parameterTypes = parameterTypes; + } + } + private final NativeLibrary nativeLibrary; - private final Class interfaceClass; + private final Class interfaceClass; // Library invocation options - private final Map options; + private final Map options; private final InvocationMapper invocationMapper; - private final Map functions = new WeakHashMap(); - public Handler(String libname, Class interfaceClass, Map options) { + private final Map functions = new WeakHashMap(); + public Handler(String libname, Class interfaceClass, Map options) { if (libname != null && "".equals(libname.trim())) { - throw new IllegalArgumentException("Invalid library name \"" - + libname + "\""); + throw new IllegalArgumentException("Invalid library name \"" + libname + "\""); + } + + if (!interfaceClass.isInterface()) { + throw new IllegalArgumentException(libname + " does not implement an interface: " + interfaceClass.getName()); } this.interfaceClass = interfaceClass; - options = new HashMap(options); - int callingConvention = - AltCallingConvention.class.isAssignableFrom(interfaceClass) - ? Function.ALT_CONVENTION : Function.C_CONVENTION; - if (options.get(OPTION_CALLING_CONVENTION) == null) { - options.put(OPTION_CALLING_CONVENTION, - new Integer(callingConvention)); - } - if (options.get(OPTION_CLASSLOADER) == null) { - options.put(OPTION_CLASSLOADER, interfaceClass.getClassLoader()); - } - this.options = options; - this.nativeLibrary = NativeLibrary.getInstance(libname, options); - invocationMapper = (InvocationMapper)options.get(OPTION_INVOCATION_MAPPER); + this.options = new HashMap(options); + int callingConvention = AltCallingConvention.class.isAssignableFrom(interfaceClass) + ? Function.ALT_CONVENTION + : Function.C_CONVENTION; + if (this.options.get(OPTION_CALLING_CONVENTION) == null) { + this.options.put(OPTION_CALLING_CONVENTION, Integer.valueOf(callingConvention)); + } + if (this.options.get(OPTION_CLASSLOADER) == null) { + this.options.put(OPTION_CLASSLOADER, interfaceClass.getClassLoader()); + } + this.nativeLibrary = NativeLibrary.getInstance(libname, this.options); + invocationMapper = (InvocationMapper)this.options.get(OPTION_INVOCATION_MAPPER); } public NativeLibrary getNativeLibrary() { return nativeLibrary; } - + public String getLibraryName() { return nativeLibrary.getName(); } - public Class getInterfaceClass() { + public Class getInterfaceClass() { return interfaceClass; } - - /** - * FunctionInfo has to be immutable to to make the object visible - * to other threads fully initialized. This is a prerequisite for - * using the class in the double checked locking scenario of {@link Handler#invoke(Object, Method, Object[])} - */ - private static final class FunctionInfo { - - FunctionInfo(InvocationHandler handler, Function function, Class[] parameterTypes, boolean isVarArgs, Map options) { - super(); - this.handler = handler; - this.function = function; - this.isVarArgs = isVarArgs; - this.options = options; - this.parameterTypes = parameterTypes; - } - - final InvocationHandler handler; - final Function function; - final boolean isVarArgs; - final Map options; - final Class[] parameterTypes; - } + @Override public Object invoke(Object proxy, Method method, Object[] inArgs) throws Throwable { // Intercept Object methods if (OBJECT_TOSTRING.equals(method)) { return "Proxy interface to " + nativeLibrary; - } - else if (OBJECT_HASHCODE.equals(method)) { - return new Integer(hashCode()); - } - else if (OBJECT_EQUALS.equals(method)) { + } else if (OBJECT_HASHCODE.equals(method)) { + return Integer.valueOf(hashCode()); + } else if (OBJECT_EQUALS.equals(method)) { Object o = inArgs[0]; if (o != null && Proxy.isProxyClass(o.getClass())) { return Function.valueOf(Proxy.getInvocationHandler(o) == this); } return Boolean.FALSE; } - + // Using the double-checked locking pattern to speed up function calls - FunctionInfo f = (FunctionInfo)functions.get(method); + FunctionInfo f = functions.get(method); if(f == null) { synchronized(functions) { - f = (FunctionInfo)functions.get(method); + f = functions.get(method); if (f == null) { boolean isVarArgs = Function.isVarArgs(method); InvocationHandler handler = null; @@ -213,13 +221,13 @@ handler = invocationMapper.getInvocationHandler(nativeLibrary, method); } Function function = null; - Class[] parameterTypes = null; - Map options = null; + Class[] parameterTypes = null; + Map options = null; if (handler == null) { // 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 -Nru libjna-java-4.2.2/src/com/sun/jna/Memory.java libjna-java-4.4.0/src/com/sun/jna/Memory.java --- libjna-java-4.2.2/src/com/sun/jna/Memory.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/Memory.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,31 +1,41 @@ -/* This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

      - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. +/* 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.lang.ref.Reference; import java.lang.ref.WeakReference; import java.nio.ByteBuffer; +import java.util.Collection; import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; +import java.util.LinkedList; import java.util.Map; -import java.util.Set; import java.util.WeakHashMap; /** - * A Pointer to memory obtained from the native heap via a + * A Pointer to memory obtained from the native heap via a * call to malloc. * *

      In some cases it might be necessary to use memory obtained from - * malloc. For example, Memory helps + * malloc. For example, Memory helps * accomplish the following idiom: *

        * 		void *buf = malloc(BUF_LEN * sizeof(char));
      @@ -42,29 +52,25 @@
        * @see Pointer
        */
       public class Memory extends Pointer {
      -
      -    private static final Map buffers;
           /** Keep track of all allocated memory so we can dispose of it before unloading. */
      -    private static final Map allocatedMemory;
      +    private static final Map> allocatedMemory =
      +            Collections.synchronizedMap(new WeakHashMap>());
       
      -    static {
      -        buffers = Collections.synchronizedMap(Platform.HAS_BUFFERS
      -                                              ? (Map)new WeakIdentityHashMap()
      -                                              : (Map)new HashMap());
      -        allocatedMemory = Collections.synchronizedMap(new WeakHashMap());
      -    }
      +    private static final WeakMemoryHolder buffers = new WeakMemoryHolder();
       
           /** Force cleanup of memory that has associated NIO Buffers which have
               been GC'd.
           */
           public static void purge() {
      -        buffers.size();
      +        buffers.clean();
           }
       
           /** Dispose of all allocated memory. */
           public static void disposeAll() {
      -        for (Iterator i=allocatedMemory.keySet().iterator();i.hasNext();) {
      -            ((Memory)i.next()).dispose();
      +        // use a copy since dispose() modifies the map
      +        Collection refs = new LinkedList(allocatedMemory.keySet());
      +        for (Memory r : refs) {
      +            r.dispose();
               }
           }
       
      @@ -79,18 +85,21 @@
                   this.peer = Memory.this.peer + offset;
               }
               /** No need to free memory. */
      +        @Override
               protected void dispose() {
                   this.peer = 0;
      -        } 
      +        }
               /** Pass bounds check to parent. */
      +        @Override
               protected void boundsCheck(long off, long sz) {
                   Memory.this.boundsCheck(this.peer - Memory.this.peer + off, sz);
               }
      +        @Override
               public String toString() {
                   return super.toString() + " (shared from " + Memory.this.toString() + ")";
               }
           }
      -    
      +
           /**
            * Allocate space in the native heap via a call to C's malloc.
            *
      @@ -100,39 +109,43 @@
               this.size = size;
               if (size <= 0) {
                   throw new IllegalArgumentException("Allocation size must be greater than zero");
      -        } 
      +        }
               peer = malloc(size);
      -        if (peer == 0) 
      +        if (peer == 0)
                   throw new OutOfMemoryError("Cannot allocate " + size + " bytes");
       
      -        allocatedMemory.put(this, new WeakReference(this));
      +        allocatedMemory.put(this, new WeakReference(this));
           }
       
      -    protected Memory() { }
      +    protected Memory() {
      +        super();
      +    }
       
           /** Provide a view of this memory using the given offset as the base address.  The
            * returned {@link Pointer} will have a size equal to that of the original
            * minus the offset.
            * @throws IndexOutOfBoundsException if the requested memory is outside
      -     * the allocated bounds. 
      +     * the allocated bounds.
            */
      +    @Override
           public Pointer share(long offset) {
               return share(offset, size() - offset);
           }
      -    
      +
           /** Provide a view of this memory using the given offset as the base
      -     * address, bounds-limited with the given size.  Maintains a reference to 
      +     * address, bounds-limited with the given size.  Maintains a reference to
            * the original {@link Memory} object to avoid GC as long as the shared
            * memory is referenced.
            * @throws IndexOutOfBoundsException if the requested memory is outside
      -     * the allocated bounds. 
      +     * the allocated bounds.
            */
      +    @Override
           public Pointer share(long offset, long sz) {
               boundsCheck(offset, sz);
               return new SharedMemory(offset, sz);
           }
      -    
      -    /** Provide a view onto this structure with the given alignment. 
      +
      +    /** Provide a view onto this structure with the given alignment.
            * @param byteBoundary Align memory to this number of bytes; should be a
            * power of two.
            * @throws IndexOutOfBoundsException if the requested alignment can
      @@ -147,7 +160,7 @@
               for (int i=0;i < 32;i++) {
                   if (byteBoundary == (1<malloc space, a la
      -     * Pointer.read.  But this method performs a bounds 
      +     * Pointer.read.  But this method performs a bounds
            * checks to ensure that the indirection does not cause memory outside the
            * malloced space to be accessed.
            *
      -     * @see Pointer#read(long,byte[],int,int) 
      +     * @see Pointer#read(long,byte[],int,int)
            */
      +    @Override
           public void read(long bOff, byte[] buf, int index, int length) {
               boundsCheck(bOff, length * 1L);
               super.read(bOff, buf, index, length);
           }
       
      -
           /**
            * Indirect the native pointer to malloc space, a la
      -     * Pointer.read.  But this method performs a bounds 
      +     * Pointer.read.  But this method performs a bounds
            * checks to ensure that the indirection does not cause memory outside the
            * malloced space to be accessed.
            *
            * @see Pointer#read(long,short[],int,int)
            */
      +    @Override
           public void read(long bOff, short[] buf, int index, int length) {
               boundsCheck(bOff, length * 2L);
               super.read(bOff, buf, index, length);
           }
       
      -
           /**
            * Indirect the native pointer to malloc space, a la
      -     * Pointer.read.  But this method performs a bounds 
      +     * Pointer.read.  But this method performs a bounds
            * checks to ensure that the indirection does not cause memory outside the
            * malloced space to be accessed.
            *
      -     * @see Pointer#read(long,char[],int,int) 
      +     * @see Pointer#read(long,char[],int,int)
            */
      +    @Override
           public void read(long bOff, char[] buf, int index, int length) {
               boundsCheck(bOff, length * 2L);
               super.read(bOff, buf, index, length);
           }
       
      -
           /**
            * Indirect the native pointer to malloc space, a la
      -     * Pointer.read.  But this method performs a bounds 
      +     * Pointer.read.  But this method performs a bounds
            * checks to ensure that the indirection does not cause memory outside the
            * malloced space to be accessed.
            *
            * @see Pointer#read(long,int[],int,int)
            */
      +    @Override
           public void read(long bOff, int[] buf, int index, int length) {
               boundsCheck(bOff, length * 4L);
               super.read(bOff, buf, index, length);
           }
       
      -
           /**
            * Indirect the native pointer to malloc space, a la
      -     * Pointer.read.  But this method performs a bounds 
      +     * Pointer.read.  But this method performs a bounds
            * checks to ensure that the indirection does not cause memory outside the
            * malloced space to be accessed.
            *
      -     * @see Pointer#read(long,long[],int,int) 
      +     * @see Pointer#read(long,long[],int,int)
            */
      +    @Override
           public void read(long bOff, long[] buf, int index, int length) {
               boundsCheck(bOff, length * 8L);
               super.read(bOff, buf, index, length);
           }
       
      -
           /**
            * Indirect the native pointer to malloc space, a la
      -     * Pointer.read.  But this method performs a bounds 
      +     * Pointer.read.  But this method performs a bounds
            * checks to ensure that the indirection does not cause memory outside the
            * malloced space to be accessed.
            *
      -     * @see Pointer#read(long,float[],int,int) 
      +     * @see Pointer#read(long,float[],int,int)
            */
      +    @Override
           public void read(long bOff, float[] buf, int index, int length) {
               boundsCheck(bOff, length * 4L);
               super.read(bOff, buf, index, length);
           }
       
      -
           /**
            * Indirect the native pointer to malloc space, a la
            * Pointer.read.  But this method performs a bounds checks to
            * ensure that the indirection does not cause memory outside the
            * malloced space to be accessed.
            *
      -     * @see Pointer#read(long,double[],int,int) 
      +     * @see Pointer#read(long,double[],int,int)
            */
      -    public void read(long bOff, double[] buf, int index, int length) 
      -    {
      +    @Override
      +    public void read(long bOff, double[] buf, int index, int length) {
               boundsCheck(bOff, length * 8L);
               super.read(bOff, buf, index, length);
           }
       
      -
      -
      -
           //////////////////////////////////////////////////////////////////////////
           // Raw write methods
           //////////////////////////////////////////////////////////////////////////
       
           /**
            * Indirect the native pointer to malloc space, a la
      -     * Pointer.write.  But this method performs a bounds 
      +     * Pointer.write.  But this method performs a bounds
            * checks to ensure that the indirection does not cause memory outside the
            * malloced space to be accessed.
            *
      -     * @see Pointer#write(long,byte[],int,int) 
      +     * @see Pointer#write(long,byte[],int,int)
            */
      +    @Override
           public void write(long bOff, byte[] buf, int index, int length) {
               boundsCheck(bOff, length * 1L);
               super.write(bOff, buf, index, length);
           }
       
      -
           /**
            * Indirect the native pointer to malloc space, a la
      -     * Pointer.write.  But this method performs a bounds 
      +     * Pointer.write.  But this method performs a bounds
            * checks to ensure that the indirection does not cause memory outside the
            * malloced space to be accessed.
            *
            * @see Pointer#write(long,short[],int,int)
            */
      +    @Override
           public void write(long bOff, short[] buf, int index, int length) {
               boundsCheck(bOff, length * 2L);
               super.write(bOff, buf, index, length);
           }
       
      -
           /**
            * Indirect the native pointer to malloc space, a la
      -     * Pointer.write.  But this method performs a bounds 
      +     * Pointer.write.  But this method performs a bounds
            * checks to ensure that the indirection does not cause memory outside the
            * malloced space to be accessed.
            *
            * @see Pointer#write(long,char[],int,int)
            */
      +    @Override
           public void write(long bOff, char[] buf, int index, int length) {
               boundsCheck(bOff, length * 2L);
               super.write(bOff, buf, index, length);
           }
       
      -
           /**
            * Indirect the native pointer to malloc space, a la
      -     * Pointer.write.  But this method performs a bounds 
      +     * Pointer.write.  But this method performs a bounds
            * checks to ensure that the indirection does not cause memory outside the
            * malloced space to be accessed.
            *
      -     * @see Pointer#write(long,int[],int,int) 
      +     * @see Pointer#write(long,int[],int,int)
            */
      +    @Override
           public void write(long bOff, int[] buf, int index, int length) {
               boundsCheck(bOff, length * 4L);
               super.write(bOff, buf, index, length);
           }
       
      -
           /**
            * Indirect the native pointer to malloc space, a la
      -     * Pointer.write.  But this method performs a bounds 
      +     * Pointer.write.  But this method performs a bounds
            * checks to ensure that the indirection does not cause memory outside the
            * malloced space to be accessed.
            *
      -     * @see Pointer#write(long,long[],int,int) 
      +     * @see Pointer#write(long,long[],int,int)
            */
      +    @Override
           public void write(long bOff, long[] buf, int index, int length) {
               boundsCheck(bOff, length * 8L);
               super.write(bOff, buf, index, length);
           }
       
      -
           /**
            * Indirect the native pointer to malloc space, a la
      -     * Pointer.write.  But this method performs a bounds 
      +     * Pointer.write.  But this method performs a bounds
            * checks to ensure that the indirection does not cause memory outside the
            * malloced space to be accessed.
            *
            * @see Pointer#write(long,float[],int,int)
            */
      +    @Override
           public void write(long bOff, float[] buf, int index, int length) {
               boundsCheck(bOff, length * 4L);
               super.write(bOff, buf, index, length);
           }
       
      -
           /**
            * Indirect the native pointer to malloc space, a la
      -     * Pointer.write.  But this method performs a bounds 
      +     * Pointer.write.  But this method performs a bounds
            * checks to ensure that the indirection does not cause memory outside the
            * malloced space to be accessed.
            *
      -     * @see Pointer#write(long,double[],int,int) 
      +     * @see Pointer#write(long,double[],int,int)
            */
      +    @Override
           public void write(long bOff, double[] buf, int index, int length) {
               boundsCheck(bOff, length * 8L);
               super.write(bOff, buf, index, length);
           }
       
      -
      -
      -
           //////////////////////////////////////////////////////////////////////////
           // Java type read methods
           //////////////////////////////////////////////////////////////////////////
       
           /**
            * Indirect the native pointer to malloc space, a la
      -     * Pointer.getByte.  But this method performs a bounds 
      +     * Pointer.getByte.  But this method performs a bounds
            * checks to ensure that the indirection does not cause memory outside the
            * malloced space to be accessed.
            *
            * @see Pointer#getByte(long)
            */
      +    @Override
           public byte getByte(long offset) {
               boundsCheck(offset, 1);
               return super.getByte(offset);
           }
       
      -
           /**
            * Indirect the native pointer to malloc space, a la
      -     * Pointer.getByte.  But this method performs a bounds 
      +     * Pointer.getByte.  But this method performs a bounds
            * checks to ensure that the indirection does not cause memory outside the
            * malloced space to be accessed.
            *
            * @see Pointer#getByte(long)
            */
      +    @Override
           public char getChar(long offset) {
               boundsCheck(offset, 1);
               return super.getChar(offset);
           }
       
      -
           /**
            * Indirect the native pointer to malloc space, a la
            * Pointer.getShort.  But this method performs a bounds
      @@ -453,83 +465,84 @@
            *
            * @see Pointer#getShort(long)
            */
      +    @Override
           public short getShort(long offset) {
               boundsCheck(offset, 2);
               return super.getShort(offset);
           }
       
      -
           /**
            * Indirect the native pointer to malloc space, a la
      -     * Pointer.getInt.  But this method performs a bounds 
      +     * Pointer.getInt.  But this method performs a bounds
            * checks to ensure that the indirection does not cause memory outside the
            * malloced space to be accessed.
            *
            * @see Pointer#getInt(long)
            */
      +    @Override
           public int getInt(long offset) {
               boundsCheck(offset, 4);
               return super.getInt(offset);
           }
       
      -
           /**
            * Indirect the native pointer to malloc space, a la
      -     * Pointer.getLong.  But this method performs a bounds 
      +     * Pointer.getLong.  But this method performs a bounds
            * checks to ensure that the indirection does not cause memory outside the
            * malloced space to be accessed.
            *
            * @see Pointer#getLong(long)
            */
      +    @Override
           public long getLong(long offset) {
               boundsCheck(offset, 8);
               return super.getLong(offset);
           }
       
      -
           /**
            * Indirect the native pointer to malloc space, a la
      -     * Pointer.getFloat.  But this method performs a bounds 
      +     * Pointer.getFloat.  But this method performs a bounds
            * checks to ensure that the indirection does not cause memory outside the
            * malloced space to be accessed.
            *
            * @see Pointer#getFloat(long)
            */
      +    @Override
           public float getFloat(long offset) {
               boundsCheck(offset, 4);
               return super.getFloat(offset);
           }
       
      -
           /**
            * Indirect the native pointer to malloc space, a la
      -     * Pointer.getDouble.  But this method performs a 
      -     * bounds check to ensure that the indirection does not cause memory 
      +     * Pointer.getDouble.  But this method performs a
      +     * bounds check to ensure that the indirection does not cause memory
            * outside the malloced space to be accessed.
            *
            * @see Pointer#getDouble(long)
            */
      +    @Override
           public double getDouble(long offset) {
               boundsCheck(offset, 8);
               return super.getDouble(offset);
           }
       
      -
           /**
            * Indirect the native pointer to malloc space, a la
      -     * Pointer.getPointer.  But this method performs 
      -     * a bounds checks to ensure that the indirection does not cause memory 
      +     * Pointer.getPointer.  But this method performs
      +     * a bounds checks to ensure that the indirection does not cause memory
            * outside the malloced space to be accessed.
            *
            * @see Pointer#getPointer(long)
            */
      +    @Override
           public Pointer getPointer(long offset) {
               boundsCheck(offset, Pointer.SIZE);
               return super.getPointer(offset);
           }
       
           /**
      -     * Get a ByteBuffer mapped to a portion of this memory.  
      +     * Get a ByteBuffer mapped to a portion of this memory.
            * We keep a weak reference to all ByteBuffers provided so that this
            * memory object is not GC'd while there are still implicit outstanding
            * references to it (it'd be nice if we could attach our own reference to
      @@ -538,8 +551,9 @@
            *
            * @param offset byte offset from pointer to start the buffer
            * @param length Length of ByteBuffer
      -     * @return a direct ByteBuffer that accesses the memory being pointed to, 
      +     * @return a direct ByteBuffer that accesses the memory being pointed to,
            */
      +    @Override
           public ByteBuffer getByteBuffer(long offset, long length) {
               boundsCheck(offset, length);
               ByteBuffer b = super.getByteBuffer(offset, length);
      @@ -549,12 +563,14 @@
               return b;
           }
       
      +    @Override
           public String getString(long offset, String encoding) {
               // NOTE: we only make sure the start of the string is within bounds
               boundsCheck(offset, 0);
               return super.getString(offset, encoding);
           }
       
      +    @Override
           public String getWideString(long offset) {
               // NOTE: we only make sure the start of the string is within bounds
               boundsCheck(offset, 0);
      @@ -567,132 +583,135 @@
       
           /**
            * Indirect the native pointer to malloc space, a la
      -     * Pointer.setByte.  But this method performs a bounds 
      +     * Pointer.setByte.  But this method performs a bounds
            * checks to ensure that the indirection does not cause memory outside the
            * malloced space to be accessed.
            *
            * @see Pointer#setByte
            */
      +    @Override
           public void setByte(long offset, byte value) {
               boundsCheck(offset, 1);
               super.setByte(offset, value);
           }
       
      -
           /**
            * Indirect the native pointer to malloc space, a la
      -     * Pointer.setChar.  But this method performs a bounds 
      +     * Pointer.setChar.  But this method performs a bounds
            * checks to ensure that the indirection does not cause memory outside the
            * malloced space to be accessed.
            *
            * @see Pointer#setChar
            */
      +    @Override
           public void setChar(long offset, char value) {
               boundsCheck(offset, Native.WCHAR_SIZE);
               super.setChar(offset, value);
           }
       
      -
           /**
            * Indirect the native pointer to malloc space, a la
      -     * Pointer.setShort.  But this method performs a bounds 
      +     * Pointer.setShort.  But this method performs a bounds
            * checks to ensure that the indirection does not cause memory outside the
            * malloced space to be accessed.
            *
            * @see Pointer#setShort
            */
      +    @Override
           public void setShort(long offset, short value) {
               boundsCheck(offset, 2);
               super.setShort(offset, value);
           }
       
      -
           /**
            * Indirect the native pointer to malloc space, a la
      -     * Pointer.setInt.  But this method performs a bounds 
      +     * Pointer.setInt.  But this method performs a bounds
            * checks to ensure that the indirection does not cause memory outside the
            * malloced space to be accessed.
            *
            * @see Pointer#setInt
            */
      +    @Override
           public void setInt(long offset, int value) {
               boundsCheck(offset, 4);
               super.setInt(offset, value);
           }
       
      -
           /**
            * Indirect the native pointer to malloc space, a la
      -     * Pointer.setLong.  But this method performs a bounds 
      +     * Pointer.setLong.  But this method performs a bounds
            * checks to ensure that the indirection does not cause memory outside the
            * malloced space to be accessed.
            *
            * @see Pointer#setLong
            */
      +    @Override
           public void setLong(long offset, long value) {
               boundsCheck(offset, 8);
               super.setLong(offset, value);
           }
       
      -
           /**
            * Indirect the native pointer to malloc space, a la
      -     * Pointer.setFloat.  But this method performs a bounds 
      +     * Pointer.setFloat.  But this method performs a bounds
            * checks to ensure that the indirection does not cause memory outside the
            * malloced space to be accessed.
            *
            * @see Pointer#setFloat
            */
      +    @Override
           public void setFloat(long offset, float value) {
               boundsCheck(offset, 4);
               super.setFloat(offset, value);
           }
       
      -
           /**
            * Indirect the native pointer to malloc space, a la
      -     * Pointer.setDouble.  But this method performs a 
      -     * bounds checks to ensure that the indirection does not cause memory 
      +     * Pointer.setDouble.  But this method performs a
      +     * bounds checks to ensure that the indirection does not cause memory
            * outside the malloced space to be accessed.
            *
            * @see Pointer#setDouble
            */
      +    @Override
           public void setDouble(long offset, double value) {
               boundsCheck(offset, 8);
               super.setDouble(offset, value);
           }
       
      -
           /**
            * Indirect the native pointer to malloc space, a la
      -     * Pointer.setPointer.  But this method performs 
      -     * a bounds checks to ensure that the indirection does not cause memory 
      +     * Pointer.setPointer.  But this method performs
      +     * a bounds checks to ensure that the indirection does not cause memory
            * outside the malloced space to be accessed.
            *
            * @see Pointer#setPointer
            */
      +    @Override
           public void setPointer(long offset, Pointer value) {
               boundsCheck(offset, Pointer.SIZE);
               super.setPointer(offset, value);
           }
       
      +    @Override
           public void setString(long offset, String value, String encoding) {
               boundsCheck(offset, Native.getBytes(value, encoding).length + 1L);
               super.setString(offset, value, encoding);
           }
       
      +    @Override
           public void setWideString(long offset, String value) {
               boundsCheck(offset, (value.length() + 1L) * Native.WCHAR_SIZE);
               super.setWideString(offset, value);
           }
       
      +    @Override
           public String toString() {
      -        return "allocated@0x" + Long.toHexString(peer) + " ("
      -            + size + " bytes)";
      +        return "allocated@0x" + Long.toHexString(peer) + " (" + size + " bytes)";
           }
       
           protected static void free(long p) {
      -        // free(0) is a no-op, so avoid the overhead of the call 
      +        // free(0) is a no-op, so avoid the overhead of the call
               if (p != 0) {
                   Native.free(p);
               }
      diff -Nru libjna-java-4.2.2/src/com/sun/jna/MethodParameterContext.java libjna-java-4.4.0/src/com/sun/jna/MethodParameterContext.java
      --- libjna-java-4.2.2/src/com/sun/jna/MethodParameterContext.java	2016-03-16 14:37:28.000000000 +0000
      +++ libjna-java-4.4.0/src/com/sun/jna/MethodParameterContext.java	2017-03-14 19:31:03.000000000 +0000
      @@ -1,14 +1,25 @@
       /* Copyright (c) 2007 Wayne Meissner, All Rights Reserved
        * 
      - * This library is free software; you can redistribute it and/or
      - * modify it under the terms of the GNU Lesser General Public
      - * License as published by the Free Software Foundation; either
      - * version 2.1 of the License, or (at your option) any later version.
      - * 
      - * This library is distributed in the hope that it will be useful,
      - * but WITHOUT ANY WARRANTY; without even the implied warranty of
      - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      - * Lesser General Public License for more details.  
      + * 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;
      diff -Nru libjna-java-4.2.2/src/com/sun/jna/MethodResultContext.java libjna-java-4.4.0/src/com/sun/jna/MethodResultContext.java
      --- libjna-java-4.2.2/src/com/sun/jna/MethodResultContext.java	2016-03-16 14:37:28.000000000 +0000
      +++ libjna-java-4.4.0/src/com/sun/jna/MethodResultContext.java	2017-03-14 19:31:03.000000000 +0000
      @@ -1,14 +1,25 @@
       /* Copyright (c) 2007 Wayne Meissner, 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).
        * 
      - * This library is free software; you can redistribute it and/or
      - * modify it under the terms of the GNU Lesser General Public
      - * License as published by the Free Software Foundation; either
      - * version 2.1 of the License, or (at your option) any later version.
      - * 
      - * This library is distributed in the hope that it will be useful,
      - * but WITHOUT ANY WARRANTY; without even the implied warranty of
      - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      - * Lesser General Public License for more details.  
      + * 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;
      @@ -20,11 +31,13 @@
        */
       public class MethodResultContext extends FunctionResultContext {
           private final Method method;
      -    MethodResultContext(Class resultClass, Function function, Object[] args, 
      -            Method method) {
      +    MethodResultContext(Class resultClass, Function function, Object[] args, Method method) {
               super(resultClass, function, args);
      -        this.method = method;        
      +        this.method = method;
      +    }
      +
      +    /** @return The {@link Method} used to invoke this function call. */
      +    public Method getMethod() {
      +        return method;
           }
      -    /** Get the Method used to invoke this function call. */
      -    public Method getMethod() { return method; }
       }
      diff -Nru libjna-java-4.2.2/src/com/sun/jna/Native.java libjna-java-4.4.0/src/com/sun/jna/Native.java
      --- libjna-java-4.2.2/src/com/sun/jna/Native.java	2016-03-16 14:37:28.000000000 +0000
      +++ libjna-java-4.4.0/src/com/sun/jna/Native.java	2017-03-14 19:31:03.000000000 +0000
      @@ -1,14 +1,25 @@
       /* Copyright (c) 2007-2015 Timothy Wall, All Rights Reserved
        *
      - * This library is free software; you can redistribute it and/or
      - * modify it under the terms of the GNU Lesser General Public
      - * License as published by the Free Software Foundation; either
      - * version 2.1 of the License, or (at your option) any later version.
      - * 

      - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; @@ -22,6 +33,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; +import java.lang.ref.Reference; import java.lang.ref.WeakReference; import java.lang.reflect.Array; import java.lang.reflect.Field; @@ -35,13 +47,13 @@ import java.net.URLClassLoader; import java.nio.Buffer; import java.nio.ByteBuffer; +import java.nio.charset.Charset; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.StringTokenizer; @@ -76,7 +88,7 @@ * failure if the JNA native library is not properly installed on the system), * set the system property jna.nounpack=true. *

      - *

      While this class and its corresponding native library are loaded, the + *

      While this class and its corresponding native library are loaded, the * system property jna.loaded will be set. The property will be * cleared when native support has been unloaded (i.e. the Native class and * its underlying native support has been GC'd).

      @@ -95,14 +107,15 @@ */ public final class Native implements Version { - public static final String DEFAULT_ENCODING = "utf8"; + public static final String DEFAULT_ENCODING = Charset.defaultCharset().name(); public static boolean DEBUG_LOAD = Boolean.getBoolean("jna.debug_load"); public static boolean DEBUG_JNA_LOAD = Boolean.getBoolean("jna.debug_load.jna"); // Used by tests, do not remove static String jnidispatchPath = null; - private static Map options = new WeakHashMap(); - private static Map libraries = new WeakHashMap(); + private static final Map, Map> typeOptions = new WeakHashMap, Map>(); + private static final Map, Reference> libraries = new WeakHashMap, Reference>(); + private static final String _OPTION_ENCLOSING_LIBRARY = "enclosing-library"; private static final UncaughtExceptionHandler DEFAULT_HANDLER = new UncaughtExceptionHandler() { @Override @@ -123,37 +136,65 @@ public static final int WCHAR_SIZE; /** Size of a native size_t type, in bytes. */ public static final int SIZE_T_SIZE; + /** Size of a native bool type (C99 and later), in bytes. */ + public static final int BOOL_SIZE; private static final int TYPE_VOIDP = 0; private static final int TYPE_LONG = 1; private static final int TYPE_WCHAR_T = 2; private static final int TYPE_SIZE_T = 3; + private static final int TYPE_BOOL = 4; static final int MAX_ALIGNMENT; static final int MAX_PADDING; + @Deprecated public static float parseVersion(String v) { return Float.parseFloat(v.substring(0, v.lastIndexOf("."))); } + + /** + * Version string must have the structure .. + * a bugfix change in the native code increments revision, the minor is + * incremented for backwards compatible changes and the major version + * is changed for backwards incompatbile changes. + * + * @param expectedVersion + * @param nativeVersion + * @return true if nativeVersion describes a version compatible to expectedVersion + */ + static boolean isCompatibleVersion(String expectedVersion, String nativeVersion) { + String[] expectedVersionParts = expectedVersion.split("\\."); + String[] nativeVersionParts = nativeVersion.split("\\."); + if(expectedVersionParts.length < 3 || nativeVersionParts.length < 3) { + return false; + } + + int expectedMajor = Integer.parseInt(expectedVersionParts[0]); + int nativeMajor = Integer.parseInt(nativeVersionParts[0]); + int expectedMinor = Integer.parseInt(expectedVersionParts[1]); + int nativeMinor = Integer.parseInt(nativeVersionParts[1]); + + if(expectedMajor != nativeMajor) { + return false; + } + + if(expectedMinor > nativeMinor) { + return false; + } + + return true; + } static { loadNativeDispatchLibrary(); - POINTER_SIZE = sizeof(TYPE_VOIDP); - LONG_SIZE = sizeof(TYPE_LONG); - WCHAR_SIZE = sizeof(TYPE_WCHAR_T); - SIZE_T_SIZE = sizeof(TYPE_SIZE_T); - // Perform initialization of other JNA classes until *after* - // initializing the above final fields - initIDs(); - if (Boolean.getBoolean("jna.protected")) { - setProtected(true); - } - float version = parseVersion(getNativeVersion()); - if (version != parseVersion(VERSION_NATIVE)) { + if (! isCompatibleVersion(VERSION_NATIVE, getNativeVersion())) { String LS = System.getProperty("line.separator"); throw new Error(LS + LS + "There is an incompatible JNA native library installed on this system" + LS + + "Expected: " + VERSION_NATIVE + LS + + "Found: " + getNativeVersion() + LS + (jnidispatchPath != null ? "(at " + jnidispatchPath + ")" : System.getProperty("java.library.path")) + "." + LS @@ -163,6 +204,19 @@ + " - set jna.boot.library.path to include the path to the version of the " + LS + " jnidispatch library included with the JNA jar file you are using" + LS); } + + POINTER_SIZE = sizeof(TYPE_VOIDP); + LONG_SIZE = sizeof(TYPE_LONG); + WCHAR_SIZE = sizeof(TYPE_WCHAR_T); + SIZE_T_SIZE = sizeof(TYPE_SIZE_T); + BOOL_SIZE = sizeof(TYPE_BOOL); + + // Perform initialization of other JNA classes until *after* + // initializing the above final fields + initIDs(); + if (Boolean.getBoolean("jna.protected")) { + setProtected(true); + } MAX_ALIGNMENT = Platform.isSPARC() || Platform.isWindows() || (Platform.isLinux() && (Platform.isARM() || Platform.isPPC())) || Platform.isAIX() @@ -329,6 +383,10 @@ * encoding. If there is no NUL terminator, the String will comprise the * entire array. * + *

      Usage note: This function assumes, that {@code buf} + * holds a {@code char} array. This means only single-byte encodings are + * supported.

      + * * @param buf The buffer containing the encoded bytes * @param encoding The encoding name - if {@code null} then the platform * default encoding will be used @@ -438,13 +496,14 @@ * the explicit interface class. * Native libraries loaded via this method may be found in * several locations. - * @param interfaceClass + * @param Type of expected wrapper + * @param interfaceClass The implementation wrapper interface * @return an instance of the requested interface, mapped to the current * process. * @throws UnsatisfiedLinkError if the library cannot be found or * dependent libraries are missing. */ - public static Object loadLibrary(Class interfaceClass) { + public static T loadLibrary(Class interfaceClass) { return loadLibrary(null, interfaceClass); } @@ -454,14 +513,16 @@ * structures and/or functions. * Native libraries loaded via this method may be found in * several locations. - * @param interfaceClass + * @param Type of expected wrapper + * @param interfaceClass The implementation wrapper interface * @param options Map of library options * @return an instance of the requested interface, mapped to the current * process. * @throws UnsatisfiedLinkError if the library cannot be found or * dependent libraries are missing. + * @see #loadLibrary(String, Class, Map) */ - public static Object loadLibrary(Class interfaceClass, Map options) { + public static T loadLibrary(Class interfaceClass, Map options) { return loadLibrary(null, interfaceClass, options); } @@ -470,15 +531,17 @@ * If name is null, attempts to map onto the current process. * Native libraries loaded via this method may be found in * several locations. - * @param name - * @param interfaceClass + * @param Type of expected wrapper + * @param name Library base name + * @param interfaceClass The implementation wrapper interface * @return an instance of the requested interface, mapped to the indicated * native library. * @throws UnsatisfiedLinkError if the library cannot be found or * dependent libraries are missing. + * @see #loadLibrary(String, Class, Map) */ - public static Object loadLibrary(String name, Class interfaceClass) { - return loadLibrary(name, interfaceClass, Collections.EMPTY_MAP); + public static T loadLibrary(String name, Class interfaceClass) { + return loadLibrary(name, interfaceClass, Collections.emptyMap()); } /** Load a library interface from the given shared library, providing @@ -488,25 +551,26 @@ * If name is null, attempts to map onto the current process. * Native libraries loaded via this method may be found in * several locations. - * @param name - * @param interfaceClass + * @param Type of expected wrapper + * @param name Library base name + * @param interfaceClass The implementation wrapper interface * @param options Map of library options * @return an instance of the requested interface, mapped to the indicated * native library. * @throws UnsatisfiedLinkError if the library cannot be found or * dependent libraries are missing. */ - public static Object loadLibrary(String name, - Class interfaceClass, - Map options) { - Library.Handler handler = - new Library.Handler(name, interfaceClass, options); + public static T loadLibrary(String name, Class interfaceClass, Map options) { + if (!Library.class.isAssignableFrom(interfaceClass)) { + throw new IllegalArgumentException("Interface (" + interfaceClass.getSimpleName() + ")" + + " of library=" + name + " does not extend " + Library.class.getSimpleName()); + } + + Library.Handler handler = new Library.Handler(name, interfaceClass, options); ClassLoader loader = interfaceClass.getClassLoader(); - Library proxy = (Library) - Proxy.newProxyInstance(loader, new Class[] {interfaceClass}, - handler); + Object proxy = Proxy.newProxyInstance(loader, new Class[] {interfaceClass}, handler); cacheOptions(interfaceClass, options, proxy); - return proxy; + return interfaceClass.cast(proxy); } /** Attempts to force initialization of an instance of the library interface @@ -514,7 +578,7 @@ * Returns whether an instance variable was instantiated. * Expects that lock on libraries is already held */ - private static void loadLibraryInstance(Class cls) { + private static void loadLibraryInstance(Class cls) { synchronized(libraries) { if (cls != null && !libraries.containsKey(cls)) { try { @@ -524,7 +588,7 @@ if (field.getType() == cls && Modifier.isStatic(field.getModifiers())) { // Ensure the field gets initialized by reading it - libraries.put(cls, new WeakReference(field.get(null))); + libraries.put(cls, new WeakReference(field.get(null))); break; } } @@ -537,18 +601,26 @@ } } - /** Find the library interface corresponding to the given class. Checks + /** + * Find the library interface corresponding to the given class. Checks * all ancestor classes and interfaces for a declaring class which * implements {@link Library}. + * @param cls The given class + * @return The enclosing class */ - static Class findEnclosingLibraryClass(Class cls) { + static Class findEnclosingLibraryClass(Class cls) { if (cls == null) { return null; } // Check for direct-mapped libraries, which won't necessarily // implement com.sun.jna.Library. synchronized(libraries) { - if (options.containsKey(cls)) { + if (typeOptions.containsKey(cls)) { + Map libOptions = typeOptions.get(cls); + Class enclosingClass = (Class)libOptions.get(_OPTION_ENCLOSING_LIBRARY); + if (enclosingClass != null) { + return enclosingClass; + } return cls; } } @@ -558,8 +630,8 @@ if (Callback.class.isAssignableFrom(cls)) { cls = CallbackReference.findCallbackClass(cls); } - Class declaring = cls.getDeclaringClass(); - Class fromDeclaring = findEnclosingLibraryClass(declaring); + Class declaring = cls.getDeclaringClass(); + Class fromDeclaring = findEnclosingLibraryClass(declaring); if (fromDeclaring != null) { return fromDeclaring; } @@ -575,42 +647,48 @@ * Map}), TYPE_MAPPER (a {@link TypeMapper}), * STRUCTURE_ALIGNMENT (an {@link Integer}), and * STRING_ENCODING (a {@link String}). - * @see Library + * + * @param type The type class + * @return The options map */ - public static Map getLibraryOptions(Class type) { + public static Map getLibraryOptions(Class type) { + Map libraryOptions; + // cached already ? synchronized(libraries) { - if (options.containsKey(type)) { - return (Map)options.get(type); + libraryOptions = typeOptions.get(type); + if (libraryOptions != null) { + return libraryOptions; } } - Class mappingClass = findEnclosingLibraryClass(type); + + Class mappingClass = findEnclosingLibraryClass(type); if (mappingClass != null) { loadLibraryInstance(mappingClass); - } - else { + } else { mappingClass = type; } + synchronized(libraries) { - if (options.containsKey(mappingClass)) { - Map libraryOptions = (Map)options.get(mappingClass); - options.put(type, libraryOptions); + libraryOptions = typeOptions.get(mappingClass); + if (libraryOptions != null) { + typeOptions.put(type, libraryOptions); // cache for next time return libraryOptions; } - Map libraryOptions = null; + try { Field field = mappingClass.getField("OPTIONS"); field.setAccessible(true); - libraryOptions = (Map)field.get(null); - } - catch (NoSuchFieldException e) { - libraryOptions = Collections.EMPTY_MAP; - } - catch (Exception e) { - throw new IllegalArgumentException("OPTIONS must be a public field of type java.util.Map (" - + e + "): " + mappingClass); + libraryOptions = (Map) field.get(null); + if (libraryOptions == null) { + throw new IllegalStateException("Null options field"); + } + } catch (NoSuchFieldException e) { + libraryOptions = Collections.emptyMap(); + } catch (Exception e) { + 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)); } @@ -620,16 +698,16 @@ if (!libraryOptions.containsKey(Library.OPTION_STRING_ENCODING)) { libraryOptions.put(Library.OPTION_STRING_ENCODING, lookupField(mappingClass, "STRING_ENCODING", String.class)); } - options.put(mappingClass, libraryOptions); + libraryOptions = cacheOptions(mappingClass, libraryOptions, null); // Store the original lookup class, if different from the mapping class if (type != mappingClass) { - options.put(type, libraryOptions); + typeOptions.put(type, libraryOptions); } return libraryOptions; } } - private static Object lookupField(Class mappingClass, String fieldName, Class resultClass) { + private static Object lookupField(Class mappingClass, String fieldName, Class resultClass) { try { Field field = mappingClass.getField(fieldName); field.setAccessible(true); @@ -648,45 +726,57 @@ /** Return the preferred {@link TypeMapper} for the given native interface. * See {@link com.sun.jna.Library#OPTION_TYPE_MAPPER}. */ - public static TypeMapper getTypeMapper(Class cls) { - return (TypeMapper)getLibraryOptions(cls).get(Library.OPTION_TYPE_MAPPER); + public static TypeMapper getTypeMapper(Class cls) { + Map options = getLibraryOptions(cls); + return (TypeMapper) options.get(Library.OPTION_TYPE_MAPPER); } - /** Return the preferred Strring encoding for the given native interface. - * If there is no setting, defaults to the {@link - * #getDefaultStringEncoding()}. - * See {@link com.sun.jna.Library#OPTION_STRING_ENCODING}. + /** + * @param cls The native interface type + * @return The preferred string encoding for the given native interface. + * If there is no setting, defaults to the {@link #getDefaultStringEncoding()}. + * @see com.sun.jna.Library#OPTION_STRING_ENCODING */ - public static String getStringEncoding(Class cls) { - String encoding = (String)getLibraryOptions(cls).get(Library.OPTION_STRING_ENCODING); + public static String getStringEncoding(Class cls) { + Map options = getLibraryOptions(cls); + String encoding = (String) options.get(Library.OPTION_STRING_ENCODING); return encoding != null ? encoding : getDefaultStringEncoding(); } - /** Return the default string encoding. Returns the value of the system + /** + * @return The default string encoding. Returns the value of the system * property jna.encoding or {@link Native#DEFAULT_ENCODING}. */ public static String getDefaultStringEncoding() { return System.getProperty("jna.encoding", DEFAULT_ENCODING); } - /** Return the preferred structure alignment for the given native interface. - * See {@link com.sun.jna.Library#OPTION_STRUCTURE_ALIGNMENT}. + /** + * @param cls The native interface type + * @return The preferred structure alignment for the given native interface. + * @see com.sun.jna.Library#OPTION_STRUCTURE_ALIGNMENT */ - public static int getStructureAlignment(Class cls) { + public static int getStructureAlignment(Class cls) { Integer alignment = (Integer)getLibraryOptions(cls).get(Library.OPTION_STRUCTURE_ALIGNMENT); return alignment == null ? Structure.ALIGN_DEFAULT : alignment.intValue(); } - /** Return a byte array corresponding to the given String. The encoding + /** + * @param s The input string + * @return A byte array corresponding to the given String. The encoding * used is obtained from {@link #getDefaultStringEncoding()}. */ static byte[] getBytes(String s) { return getBytes(s, getDefaultStringEncoding()); } - /** Return a byte array corresponding to the given String, using the given - encoding. If the encoding is not found default to the platform native - encoding. + /** + * @param s The string + * @param encoding The encoding - if {@code null} then the default platform + * encoding is used + * @return A byte array corresponding to the given String, using the given + * encoding. If the encoding is not found default to the platform native + * encoding. */ static byte[] getBytes(String s, String encoding) { if (encoding != null) { @@ -703,15 +793,21 @@ return s.getBytes(); } - /** Obtain a NUL-terminated byte buffer equivalent to the given String, - using the encoding returned by {@link #getDefaultStringEncoding()}. - */ + /** + * @param s The string + * @return A NUL-terminated byte buffer equivalent to the given String, + * using the encoding returned by {@link #getDefaultStringEncoding()}. + * @see #toByteArray(String, String) + */ public static byte[] toByteArray(String s) { return toByteArray(s, getDefaultStringEncoding()); } - /** Obtain a NUL-terminated byte buffer equivalent to the given String, - using the given encoding. + /** + * @param s The string + * @return A NUL-terminated byte buffer equivalent to the given String, + * using the given encoding. + * @see #getBytes(String, String) */ public static byte[] toByteArray(String s, String encoding) { byte[] bytes = getBytes(s, encoding); @@ -720,8 +816,9 @@ return buf; } - /** Obtain a NUL-terminated wide character buffer equivalent to the given - String. + /** + * @param s The string + * @return A NUL-terminated wide character buffer equivalent to the given string. */ public static char[] toCharArray(String s) { char[] chars = s.toCharArray(); @@ -736,7 +833,6 @@ * jar file. */ private static void loadNativeDispatchLibrary() { - if (!Boolean.getBoolean("jna.nounpack")) { try { removeTemporaryFiles(); @@ -996,7 +1092,7 @@ /** Retrieve last error set by the OS. This corresponds to * GetLastError() on Windows, and errno on * most other platforms. The value is preserved per-thread, but whether - * the original value is per-thread depends on the underlying OS. + * the original value is per-thread depends on the underlying OS. *

      * An alternative method of obtaining the last error result is * to declare your mapped method to throw {@link LastErrorException} @@ -1024,7 +1120,7 @@ * @return a synchronized view of the specified library. */ public static Library synchronizedLibrary(final Library library) { - Class cls = library.getClass(); + Class cls = library.getClass(); if (!Proxy.isProxyClass(cls)) { throw new IllegalArgumentException("Library must be a proxy class"); } @@ -1067,9 +1163,9 @@ try { final ClassLoader cl = Native.class.getClassLoader(); - Method m = (Method)AccessController.doPrivileged(new PrivilegedAction() { + Method m = AccessController.doPrivileged(new PrivilegedAction() { @Override - public Object run() { + public Method run() { try { Method m = ClassLoader.class.getDeclaredMethod("findLibrary", new Class[] { String.class }); m.setAccessible(true); @@ -1154,10 +1250,13 @@ } } - /** Returns the native size of the given class, in bytes. + /** + * @param type The Java class for which the native size is to be determined + * @param value an instance of said class (if available) + * @return the native size of the given class, in bytes. * For use with arrays. */ - public static int getNativeSize(Class type, Object value) { + public static int getNativeSize(Class type, Object value) { if (type.isArray()) { int len = Array.getLength(value); if (len > 0) { @@ -1181,11 +1280,15 @@ } } - /** Returns the native size for a given Java class. Structures are + /** + * Returns the native size for a given Java class. Structures are * assumed to be struct pointers unless they implement * {@link Structure.ByValue}. + * + * @param cls The Java class + * @return The native size for the class */ - public static int getNativeSize(Class cls) { + public static int getNativeSize(Class cls) { if (NativeMapped.class.isAssignableFrom(cls)) { cls = NativeMappedConverter.getInstance(cls).nativeType(); } @@ -1215,10 +1318,11 @@ + "\" is unknown"); } - /** Indicate whether the given class is supported as a native argument - * type. + /** + * @param cls The Java class + * @return {@code true} whether the given class is supported as a native argument type. */ - public static boolean isSupportedNativeType(Class cls) { + public static boolean isSupportedNativeType(Class cls) { if (Structure.class.isAssignableFrom(cls)) { return true; } @@ -1230,20 +1334,24 @@ } } - /** Set the default handler invoked when a callback throws an uncaught + /** + * Set the default handler invoked when a callback throws an uncaught * exception. If the given handler is null, the default * handler will be reinstated. + * + * @param eh The default handler */ public static void setCallbackExceptionHandler(UncaughtExceptionHandler eh) { callbackExceptionHandler = eh == null ? DEFAULT_HANDLER : eh; } - /** Returns the current handler for callback uncaught exceptions. */ + /** @return the current handler for callback uncaught exceptions. */ public static UncaughtExceptionHandler getCallbackExceptionHandler() { return callbackExceptionHandler; } - /** When called from a class static initializer, maps all native methods + /** + * When called from a class static initializer, maps all native methods * found within that class to native libraries via the JNA raw calling * interface. * @param libName library name to which functions should be bound @@ -1252,7 +1360,8 @@ register(findDirectMappedClass(getCallingClass()), libName); } - /** When called from a class static initializer, maps all native methods + /** + * When called from a class static initializer, maps all native methods * found within that class to native libraries via the JNA raw calling * interface. * @param lib native library to which functions should be bound @@ -1262,10 +1371,10 @@ } /** Find the nearest enclosing class with native methods. */ - static Class findDirectMappedClass(Class cls) { + static Class findDirectMappedClass(Class cls) { Method[] methods = cls.getDeclaredMethods(); - for (int i=0;i < methods.length;i++) { - if ((methods[i].getModifiers() & Modifier.NATIVE) != 0) { + for (Method m : methods) { + if ((m.getModifiers() & Modifier.NATIVE) != 0) { return cls; } } @@ -1274,8 +1383,8 @@ String name = cls.getName().substring(0, idx); try { return findDirectMappedClass(Class.forName(name, true, cls.getClassLoader())); - } - catch(ClassNotFoundException e) { + } catch(ClassNotFoundException e) { + // ignored } } throw new IllegalArgumentException("Can't determine class with native methods from the current context (" + cls + ")"); @@ -1284,10 +1393,10 @@ /** Try to determine the class context in which a {@link #register(String)} call was made. */ - static Class getCallingClass() { - Class[] context = new SecurityManager() { + static Class getCallingClass() { + Class[] context = new SecurityManager() { @Override - public Class[] getClassContext() { + public Class[] getClassContext() { return super.getClassContext(); } }.getClassContext(); @@ -1300,26 +1409,26 @@ return context[3]; } - /** Set a thread initializer for the given callback. - The thread initializer indicates desired thread configuration when the - given Callback is invoked on a native thread not yet attached to the - VM. + /** + * Set a thread initializer for the given callback. + * @param cb The callback to invoke + * @param initializer The thread initializer indicates desired thread configuration when the + * given Callback is invoked on a native thread not yet attached to the VM. */ public static void setCallbackThreadInitializer(Callback cb, CallbackThreadInitializer initializer) { CallbackReference.setCallbackThreadInitializer(cb, initializer); } - - private static Map registeredClasses = new WeakHashMap(); - private static Map registeredLibraries = new WeakHashMap(); + private static Map, long[]> registeredClasses = new WeakHashMap, long[]>(); + private static Map, NativeLibrary> registeredLibraries = new WeakHashMap, NativeLibrary>(); private static void unregisterAll() { synchronized(registeredClasses) { - for (Iterator i=registeredClasses.entrySet().iterator();i.hasNext();) { - Map.Entry e = (Map.Entry)i.next(); - unregister((Class)e.getKey(), (long[])e.getValue()); - i.remove(); + for (Map.Entry, long[]> e : registeredClasses.entrySet()) { + unregister(e.getKey(), e.getValue()); } + + registeredClasses.clear(); } } @@ -1335,27 +1444,31 @@ Should only be called if the class is no longer referenced and about to be garbage collected. */ - public static void unregister(Class cls) { + public static void unregister(Class cls) { synchronized(registeredClasses) { - if (registeredClasses.containsKey(cls)) { - unregister(cls, (long[])registeredClasses.get(cls)); + long[] handles = registeredClasses.get(cls); + if (handles != null) { + unregister(cls, handles); registeredClasses.remove(cls); registeredLibraries.remove(cls); } } } - /** @return whether the given class's native components are registered. */ - public static boolean registered(Class cls) { + /** + * @param cls The type {@link Class} + * @return whether the given class's native components are registered. + */ + public static boolean registered(Class cls) { synchronized(registeredClasses) { return registeredClasses.containsKey(cls); } } - /** Unregister the native methods for the given class. */ - private static native void unregister(Class cls, long[] handles); + /* Unregister the native methods for the given class. */ + private static native void unregister(Class cls, long[] handles); - private static String getSignature(Class cls) { + static String getSignature(Class cls) { if (cls.isArray()) { return "[" + getSignature(cls.getComponentType()); } @@ -1422,7 +1535,7 @@ private static final int CVT_TYPE_MAPPER_STRING = 24; private static final int CVT_TYPE_MAPPER_WSTRING = 25; - private static int getConversion(Class type, TypeMapper mapper) { + private static int getConversion(Class type, TypeMapper mapper) { if (type == Boolean.class) type = boolean.class; else if (type == Byte.class) type = byte.class; else if (type == Short.class) type = short.class; @@ -1437,7 +1550,7 @@ FromNativeConverter fromNative = mapper.getFromNativeConverter(type); ToNativeConverter toNative = mapper.getToNativeConverter(type); if (fromNative != null) { - Class nativeType = fromNative.nativeType(); + Class nativeType = fromNative.nativeType(); if (nativeType == String.class) { return CVT_TYPE_MAPPER_STRING; } @@ -1447,7 +1560,7 @@ return CVT_TYPE_MAPPER; } if (toNative != null) { - Class nativeType = toNative.nativeType(); + Class nativeType = toNative.nativeType(); if (nativeType == String.class) { return CVT_TYPE_MAPPER_STRING; } @@ -1502,7 +1615,7 @@ return CVT_POINTER_TYPE; } if (NativeMapped.class.isAssignableFrom(type)) { - Class nativeType = NativeMappedConverter.getInstance(type).nativeType(); + Class nativeType = NativeMappedConverter.getInstance(type).nativeType(); if (nativeType == String.class) { return CVT_NATIVE_MAPPED_STRING; } @@ -1514,7 +1627,8 @@ return CVT_UNSUPPORTED; } - /** When called from a class static initializer, maps all native methods + /** + * When called from a class static initializer, maps all native methods * found within that class to native libraries via the JNA raw calling * interface. Uses the class loader of the given class to search for the * native library in the resource path if it is not found in the system @@ -1523,10 +1637,10 @@ * @param libName name of or path to native library to which functions * should be bound */ - public static void register(Class cls, String libName) { - Map options = new HashMap(); - options.put(Library.OPTION_CLASSLOADER, cls.getClassLoader()); - register(cls, NativeLibrary.getInstance(libName, options)); + public static void register(Class cls, String libName) { + NativeLibrary library = + NativeLibrary.getInstance(libName, Collections.singletonMap(Library.OPTION_CLASSLOADER, cls.getClassLoader())); + register(cls, library); } /** When called from a class static initializer, maps all native methods @@ -1538,25 +1652,26 @@ // TODO: derive options from annotations (per-class or per-method) // options: read parameter type mapping (long/native long), // method name, library name, call conv - public static void register(Class cls, NativeLibrary lib) { + public static void register(Class cls, NativeLibrary lib) { Method[] methods = cls.getDeclaredMethods(); - List mlist = new ArrayList(); - TypeMapper mapper = (TypeMapper) - lib.getOptions().get(Library.OPTION_TYPE_MAPPER); - cacheOptions(cls, lib.getOptions(), null); - - for (int i=0;i < methods.length;i++) { - if ((methods[i].getModifiers() & Modifier.NATIVE) != 0) { - mlist.add(methods[i]); + List mlist = new ArrayList(); + Map options = lib.getOptions(); + TypeMapper mapper = (TypeMapper) options.get(Library.OPTION_TYPE_MAPPER); + options = cacheOptions(cls, options, null); + + for (Method m : methods) { + if ((m.getModifiers() & Modifier.NATIVE) != 0) { + mlist.add(m); } } + long[] handles = new long[mlist.size()]; for (int i=0;i < handles.length;i++) { - Method method = (Method)mlist.get(i); + Method method = mlist.get(i); String sig = "("; - Class rclass = method.getReturnType(); + Class rclass = method.getReturnType(); long rtype, closure_rtype; - Class[] ptypes = method.getParameterTypes(); + Class[] ptypes = method.getParameterTypes(); long[] atypes = new long[ptypes.length]; long[] closure_atypes = new long[ptypes.length]; int[] cvt = new int[ptypes.length]; @@ -1565,86 +1680,86 @@ int rcvt = getConversion(rclass, mapper); boolean throwLastError = false; switch (rcvt) { - case CVT_UNSUPPORTED: - throw new IllegalArgumentException(rclass + " is not a supported return type (in method " + method.getName() + " in " + cls + ")"); - case CVT_TYPE_MAPPER: - case CVT_TYPE_MAPPER_STRING: - case CVT_TYPE_MAPPER_WSTRING: - fromNative = mapper.getFromNativeConverter(rclass); - // FFIType.get() always looks up the native type for any given - // class, so if we actually have conversion into a Java - // object, make sure we use the proper type information - closure_rtype = FFIType.get(rclass.isPrimitive() ? rclass : Pointer.class).peer; - rtype = FFIType.get(fromNative.nativeType()).peer; - break; - case CVT_NATIVE_MAPPED: - case CVT_NATIVE_MAPPED_STRING: - case CVT_NATIVE_MAPPED_WSTRING: - case CVT_INTEGER_TYPE: - case CVT_POINTER_TYPE: - closure_rtype = FFIType.get(Pointer.class).peer; - rtype = FFIType.get(NativeMappedConverter.getInstance(rclass).nativeType()).peer; - break; - case CVT_STRUCTURE: - closure_rtype = rtype = FFIType.get(Pointer.class).peer; - break; - case CVT_STRUCTURE_BYVAL: - closure_rtype = FFIType.get(Pointer.class).peer; - rtype = FFIType.get(rclass).peer; - break; - default: - closure_rtype = rtype = FFIType.get(rclass).peer; - break; + case CVT_UNSUPPORTED: + throw new IllegalArgumentException(rclass + " is not a supported return type (in method " + method.getName() + " in " + cls + ")"); + case CVT_TYPE_MAPPER: + case CVT_TYPE_MAPPER_STRING: + case CVT_TYPE_MAPPER_WSTRING: + fromNative = mapper.getFromNativeConverter(rclass); + // FFIType.get() always looks up the native type for any given + // class, so if we actually have conversion into a Java + // object, make sure we use the proper type information + closure_rtype = FFIType.get(rclass.isPrimitive() ? rclass : Pointer.class).peer; + rtype = FFIType.get(fromNative.nativeType()).peer; + break; + case CVT_NATIVE_MAPPED: + case CVT_NATIVE_MAPPED_STRING: + case CVT_NATIVE_MAPPED_WSTRING: + case CVT_INTEGER_TYPE: + case CVT_POINTER_TYPE: + closure_rtype = FFIType.get(Pointer.class).peer; + rtype = FFIType.get(NativeMappedConverter.getInstance(rclass).nativeType()).peer; + break; + case CVT_STRUCTURE: + closure_rtype = rtype = FFIType.get(Pointer.class).peer; + break; + case CVT_STRUCTURE_BYVAL: + closure_rtype = FFIType.get(Pointer.class).peer; + rtype = FFIType.get(rclass).peer; + break; + default: + closure_rtype = rtype = FFIType.get(rclass).peer; } + for (int t=0;t < ptypes.length;t++) { - Class type = ptypes[t]; + Class type = ptypes[t]; sig += getSignature(type); - cvt[t] = getConversion(type, mapper); - if (cvt[t] == CVT_UNSUPPORTED) { + int conversionType = getConversion(type, mapper); + cvt[t] = conversionType; + if (conversionType == CVT_UNSUPPORTED) { throw new IllegalArgumentException(type + " is not a supported argument type (in method " + method.getName() + " in " + cls + ")"); } - if (cvt[t] == CVT_NATIVE_MAPPED - || cvt[t] == CVT_NATIVE_MAPPED_STRING - || cvt[t] == CVT_NATIVE_MAPPED_WSTRING - || cvt[t] == CVT_INTEGER_TYPE) { + if ((conversionType == CVT_NATIVE_MAPPED) + || (conversionType == CVT_NATIVE_MAPPED_STRING) + || (conversionType == CVT_NATIVE_MAPPED_WSTRING) + || (conversionType == CVT_INTEGER_TYPE)) { type = NativeMappedConverter.getInstance(type).nativeType(); - } - else if (cvt[t] == CVT_TYPE_MAPPER - || cvt[t] == CVT_TYPE_MAPPER_STRING - || cvt[t] == CVT_TYPE_MAPPER_WSTRING) { + } else if ((conversionType == CVT_TYPE_MAPPER) + || (conversionType == CVT_TYPE_MAPPER_STRING) + || (conversionType == CVT_TYPE_MAPPER_WSTRING)) { toNative[t] = mapper.getToNativeConverter(type); } + // Determine the type that will be passed to the native // function, as well as the type to be passed // from Java initially - switch(cvt[t]) { - case CVT_STRUCTURE_BYVAL: - case CVT_INTEGER_TYPE: - case CVT_POINTER_TYPE: - case CVT_NATIVE_MAPPED: - case CVT_NATIVE_MAPPED_STRING: - case CVT_NATIVE_MAPPED_WSTRING: - atypes[t] = FFIType.get(type).peer; - closure_atypes[t] = FFIType.get(Pointer.class).peer; - break; - case CVT_TYPE_MAPPER: - case CVT_TYPE_MAPPER_STRING: - case CVT_TYPE_MAPPER_WSTRING: - closure_atypes[t] = FFIType.get(type.isPrimitive() ? type : Pointer.class).peer; - atypes[t] = FFIType.get(toNative[t].nativeType()).peer; - break; - case CVT_DEFAULT: - closure_atypes[t] = atypes[t] = FFIType.get(type).peer; - break; - default: - closure_atypes[t] = atypes[t] = FFIType.get(Pointer.class).peer; - break; + switch(conversionType) { + case CVT_STRUCTURE_BYVAL: + case CVT_INTEGER_TYPE: + case CVT_POINTER_TYPE: + case CVT_NATIVE_MAPPED: + case CVT_NATIVE_MAPPED_STRING: + case CVT_NATIVE_MAPPED_WSTRING: + atypes[t] = FFIType.get(type).peer; + closure_atypes[t] = FFIType.get(Pointer.class).peer; + break; + case CVT_TYPE_MAPPER: + case CVT_TYPE_MAPPER_STRING: + case CVT_TYPE_MAPPER_WSTRING: + closure_atypes[t] = FFIType.get(type.isPrimitive() ? type : Pointer.class).peer; + atypes[t] = FFIType.get(toNative[t].nativeType()).peer; + break; + case CVT_DEFAULT: + closure_atypes[t] = atypes[t] = FFIType.get(type).peer; + break; + default: + closure_atypes[t] = atypes[t] = FFIType.get(Pointer.class).peer; } } sig += ")"; sig += getSignature(rclass); - Class[] etypes = method.getExceptionTypes(); + Class[] etypes = method.getExceptionTypes(); for (int e=0;e < etypes.length;e++) { if (LastErrorException.class.isAssignableFrom(etypes[e])) { throwLastError = true; @@ -1658,13 +1773,12 @@ sig, cvt, closure_atypes, atypes, rcvt, closure_rtype, rtype, - rclass, + method, f.peer, f.getCallingConvention(), throwLastError, toNative, fromNative, f.encoding); - } - catch(NoSuchMethodError e) { + } catch(NoSuchMethodError e) { throw new UnsatisfiedLinkError("No method " + method.getName() + " with signature " + sig + " in " + cls); } } @@ -1674,15 +1788,16 @@ } } - /** Take note of options used for a given library mapping, to facilitate - looking them up later. - */ - private static void cacheOptions(Class cls, Map libOptions, Object proxy) { - libOptions = new HashMap(libOptions); + /* 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); + libOptions.put(_OPTION_ENCLOSING_LIBRARY, cls); synchronized(libraries) { - options.put(cls, libOptions); + 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, @@ -1690,18 +1805,19 @@ // classes get the appropriate associated options if (!cls.isInterface() && Library.class.isAssignableFrom(cls)) { - Class ifaces[] = cls.getInterfaces(); - for (int i=0;i < ifaces.length;i++) { - if (Library.class.isAssignableFrom(ifaces[i])) { - cacheOptions(ifaces[i], libOptions, proxy); + Class ifaces[] = cls.getInterfaces(); + for (Class ifc : ifaces) { + if (Library.class.isAssignableFrom(ifc)) { + cacheOptions(ifc, libOptions, proxy); break; } } } } + return libOptions; } - private static native long registerMethod(Class cls, + private static native long registerMethod(Class cls, String name, String signature, int[] conversions, @@ -1710,7 +1826,7 @@ int rconversion, long closure_rtype, long rtype, - Class rclass, + Method method, long fptr, int callingConvention, boolean throwLastError, @@ -1720,13 +1836,17 @@ // Called from native code - private static NativeMapped fromNative(Class cls, Object value) { - // NOTE: technically should be either CallbackParameterContext or - // FunctionResultContext + private static NativeMapped fromNative(Class cls, Object value) { + // NOTE: technically should be CallbackParameterContext return (NativeMapped)NativeMappedConverter.getInstance(cls).fromNative(value, new FromNativeContext(cls)); } // Called from native code - private static Class nativeType(Class cls) { + private static NativeMapped fromNative(Method m, Object value) { + Class cls = m.getReturnType(); + return (NativeMapped)NativeMappedConverter.getInstance(cls).fromNative(value, new MethodResultContext(cls, null, null, m)); + } + // Called from native code + private static Class nativeType(Class cls) { return NativeMappedConverter.getInstance(cls).nativeType(); } // Called from native code @@ -1736,9 +1856,8 @@ return cvt.toNative(o, new ToNativeContext()); } // Called from native code - private static Object fromNative(FromNativeConverter cvt, Object o, Class cls) { - // NOTE: technically should be FunctionResultContext - return cvt.fromNative(o, new FromNativeContext(cls)); + private static Object fromNative(FromNativeConverter cvt, Object o, Method m) { + return cvt.fromNative(o, new MethodResultContext(m.getReturnType(), null, null, m)); } /** Create a new cif structure. */ @@ -1790,114 +1909,133 @@ */ static synchronized native long createNativeCallback(Callback callback, Method method, - Class[] parameterTypes, - Class returnType, + Class[] parameterTypes, + Class returnType, int callingConvention, int flags, String encoding); /** - * Call the native function being represented by this object - * @param fp function pointer - * @param callFlags calling convention to be used - * @param args - * Arguments to pass to the native function + * Call the native function. + * + * @param function Present to prevent the GC to collect the Function object + * prematurely + * @param fp function pointer + * @param callFlags calling convention to be used + * @param args Arguments to pass to the native function * - * @return The value returned by the target native function + * @return The value returned by the target native function */ - static native int invokeInt(long fp, int callFlags, Object[] args); + static native int invokeInt(Function function, long fp, int callFlags, Object[] args); /** - * Call the native function being represented by this object - * @param fp function pointer - * @param callFlags calling convention to be used - * @param args - * Arguments to pass to the native function + * Call the native function. * - * @return The value returned by the target native function + * @param function Present to prevent the GC to collect the Function object + * prematurely + * @param fp function pointer + * @param callFlags calling convention to be used + * @param args Arguments to pass to the native function + * + * @return The value returned by the target native function */ - static native long invokeLong(long fp, int callFlags, Object[] args); + static native long invokeLong(Function function, long fp, int callFlags, Object[] args); /** - * Call the native function being represented by this object - * @param fp function pointer - * @param callFlags calling convention to be used - * @param args - * Arguments to pass to the native function + * Call the native function. + * + * @param function Present to prevent the GC to collect the Function object + * prematurely + * @param fp function pointer + * @param callFlags calling convention to be used + * @param args Arguments to pass to the native function */ - static native void invokeVoid(long fp, int callFlags, Object[] args); + static native void invokeVoid(Function function, long fp, int callFlags, Object[] args); /** - * Call the native function being represented by this object - * @param fp function pointer - * @param callFlags calling convention to be used - * @param args - * Arguments to pass to the native function + * Call the native function. * - * @return The value returned by the target native function + * @param function Present to prevent the GC to collect the Function object + * prematurely + * @param fp function pointer + * @param callFlags calling convention to be used + * @param args Arguments to pass to the native function + * + * @return The value returned by the target native function */ - static native float invokeFloat(long fp, int callFlags, Object[] args); + static native float invokeFloat(Function function, long fp, int callFlags, Object[] args); /** - * Call the native function being represented by this object - * @param fp function pointer - * @param callFlags calling convention to be used - * @param args - * Arguments to pass to the native function + * Call the native function. + * + * @param function Present to prevent the GC to collect the Function object + * prematurely + * @param fp function pointer + * @param callFlags calling convention to be used + * @param args Arguments to pass to the native function * - * @return The value returned by the target native function + * @return The value returned by the target native function */ - static native double invokeDouble(long fp, int callFlags, Object[] args); + static native double invokeDouble(Function function, long fp, int callFlags, Object[] args); /** - * Call the native function being represented by this object - * @param fp function pointer - * @param callFlags calling convention to be used - * @param args - * Arguments to pass to the native function + * Call the native function. * - * @return The native pointer returned by the target native function + * @param function Present to prevent the GC to collect the Function object + * prematurely + * @param fp function pointer + * @param callFlags calling convention to be used + * @param args Arguments to pass to the native function + * + * @return The value returned by the target native function */ - static native long invokePointer(long fp, int callFlags, Object[] args); + static native long invokePointer(Function function, long fp, int callFlags, Object[] args); /** - * Call the native function being represented by this object, returning - * a struct by value. - * @param fp function pointer - * @param callFlags calling convention to be used - * @param args Arguments to pass to the native function - * @param memory Memory for pre-allocated structure to hold the result - * @param typeInfo Native type information for the Structure + * Call the native function, returning a struct by value. + * + * @param function Present to prevent the GC to collect the Function object + * prematurely + * @param fp function pointer + * @param callFlags calling convention to be used + * @param args Arguments to pass to the native function + * @param memory Memory for pre-allocated structure to hold the result + * @param typeInfo Native type information for the Structure */ - private static native void invokeStructure(long fp, int callFlags, + private static native void invokeStructure(Function function, long fp, int callFlags, Object[] args, long memory, long type_info); /** - * Call the native function being represented by this object, returning - * a struct by value. - * @param fp function pointer - * @param callFlags calling convention to be used - * @param args Arguments to pass to the native function + * Call the native function, returning a struct by value. + * + * @param function Present to prevent the GC to collect the Function object + * prematurely + * @param fp function pointer + * @param callFlags calling convention to be used + * @param args Arguments to pass to the native function + * * @return the passed-in Structure */ - static Structure invokeStructure(long fp, int callFlags, Object[] args, + static Structure invokeStructure(Function function, long fp, int callFlags, Object[] args, Structure s) { - invokeStructure(fp, callFlags, args, s.getPointer().peer, + invokeStructure(function, fp, callFlags, args, s.getPointer().peer, s.getTypeInfo().peer); return s; } /** - * Call the native function being represented by this object, returning - * a Java Object. - * @param fp function pointer - * @param callFlags calling convention to be used - * @param args Arguments to pass to the native function + * Call the native function, returning a Java Object. + * + * @param function Present to prevent the GC to collect the Function object + * prematurely + * @param fp function pointer + * @param callFlags calling convention to be used + * @param args Arguments to pass to the native function * * @return The returned Java Object */ - static native Object invokeObject(long fp, int callFlags, Object[] args); + static native Object invokeObject(Function function, long fp, int callFlags, Object[] args); /** Open the requested native library with default options. */ static long open(String name) { @@ -1914,49 +2052,80 @@ static native long findSymbol(long handle, String name); - static native long indexOf(long addr, byte value); + /* + ============================================================================ + + The first argument of the following read, write, get and set + function is present to protect it from the GC. + + Although on the native side only the baseaddr and offset are used to access + the memory, the Pointer argument must not be removed. This is the usecase: + + -------------------------------------- + Memory pointer = ; + + String result = pointer.getWideString(0) + + -------------------------------------- + + In getWideString the pointer address is resolved and is passed to native. If + the Memory object itself is not passed to native, the GC can collect the + object at that point as it is not used anymore and the finalizers could run. + + The would introduce a race between the native call and the GC running the + finalizers. The finalizers free the allocated memory, which results in + a SEGFAULT. + + Passing only the Pointer object and loading the peer value via JNI was not + implemented, as in microbenchmarks it showed large impact. Passing the + Pointer object instead of the peer and offset value to getInt resulted in + a performance of 70% of the unmodified source. + + ============================================================================ + */ + static native long indexOf(Pointer pointer, long baseaddr, long offset, byte value); - static native void read(long addr, byte[] buf, int index, int length); + static native void read(Pointer pointer, long baseaddr, long offset, byte[] buf, int index, int length); - static native void read(long addr, short[] buf, int index, int length); + static native void read(Pointer pointer, long baseaddr, long offset, short[] buf, int index, int length); - static native void read(long addr, char[] buf, int index, int length); + static native void read(Pointer pointer, long baseaddr, long offset, char[] buf, int index, int length); - static native void read(long addr, int[] buf, int index, int length); + static native void read(Pointer pointer, long baseaddr, long offset, int[] buf, int index, int length); - static native void read(long addr, long[] buf, int index, int length); + static native void read(Pointer pointer, long baseaddr, long offset, long[] buf, int index, int length); - static native void read(long addr, float[] buf, int index, int length); + static native void read(Pointer pointer, long baseaddr, long offset, float[] buf, int index, int length); - static native void read(long addr, double[] buf, int index, int length); + static native void read(Pointer pointer, long baseaddr, long offset, double[] buf, int index, int length); - static native void write(long addr, byte[] buf, int index, int length); + static native void write(Pointer pointer, long baseaddr, long offset, byte[] buf, int index, int length); - static native void write(long addr, short[] buf, int index, int length); + static native void write(Pointer pointer, long baseaddr, long offset, short[] buf, int index, int length); - static native void write(long addr, char[] buf, int index, int length); + static native void write(Pointer pointer, long baseaddr, long offset, char[] buf, int index, int length); - static native void write(long addr, int[] buf, int index, int length); + static native void write(Pointer pointer, long baseaddr, long offset, int[] buf, int index, int length); - static native void write(long addr, long[] buf, int index, int length); + static native void write(Pointer pointer, long baseaddr, long offset, long[] buf, int index, int length); - static native void write(long addr, float[] buf, int index, int length); + static native void write(Pointer pointer, long baseaddr, long offset, float[] buf, int index, int length); - static native void write(long addr, double[] buf, int index, int length); + static native void write(Pointer pointer, long baseaddr, long offset, double[] buf, int index, int length); - static native byte getByte(long addr); + static native byte getByte(Pointer pointer, long baseaddr, long offset); - static native char getChar(long addr); + static native char getChar(Pointer pointer, long baseaddr, long offset); - static native short getShort(long addr); + static native short getShort(Pointer pointer, long baseaddr, long offset); - static native int getInt(long addr); + static native int getInt(Pointer pointer, long baseaddr, long offset); - static native long getLong(long addr); + static native long getLong(Pointer pointer, long baseaddr, long offset); - static native float getFloat(long addr); + static native float getFloat(Pointer pointer, long baseaddr, long offset); - static native double getDouble(long addr); + static native double getDouble(Pointer pointer, long baseaddr, long offset); static Pointer getPointer(long addr) { long peer = _getPointer(addr); @@ -1965,14 +2134,14 @@ private static native long _getPointer(long addr); - static native String getWideString(long addr); + static native String getWideString(Pointer pointer, long baseaddr, long offset); - static String getString(long addr) { - return getString(addr, getDefaultStringEncoding()); + static String getString(Pointer pointer, long offset) { + return getString(pointer, offset, getDefaultStringEncoding()); } - static String getString(long addr, String encoding) { - byte[] data = getStringBytes(addr); + static String getString(Pointer pointer, long offset, String encoding) { + byte[] data = getStringBytes(pointer, pointer.peer, offset); if (encoding != null) { try { return new String(data, encoding); @@ -1983,28 +2152,30 @@ return new String(data); } - static native byte[] getStringBytes(long addr); + static native byte[] getStringBytes(Pointer pointer, long baseaddr, long offset); - static native void setMemory(long addr, long length, byte value); + static native void setMemory(Pointer pointer, long baseaddr, long offset, long length, byte value); - static native void setByte(long addr, byte value); + static native void setByte(Pointer pointer, long baseaddr, long offset, byte value); - static native void setShort(long addr, short value); + static native void setShort(Pointer pointer, long baseaddr, long offset, short value); - static native void setChar(long addr, char value); + static native void setChar(Pointer pointer, long baseaddr, long offset, char value); - static native void setInt(long addr, int value); + static native void setInt(Pointer pointer, long baseaddr, long offset, int value); - static native void setLong(long addr, long value); + static native void setLong(Pointer pointer, long baseaddr, long offset, long value); - static native void setFloat(long addr, float value); + static native void setFloat(Pointer pointer, long baseaddr, long offset, float value); - static native void setDouble(long addr, double value); + static native void setDouble(Pointer pointer, long baseaddr, long offset, double value); - static native void setPointer(long addr, long value); - - static native void setWideString(long addr, String value); + static native void setPointer(Pointer pointer, long baseaddr, long offset, long value); + static native void setWideString(Pointer pointer, long baseaddr, long offset, String value); + + static native ByteBuffer getDirectByteBuffer(Pointer pointer, long addr, long offset, long length); + /** * Call the real native malloc * @param size size of the memory to be allocated @@ -2026,10 +2197,23 @@ * * @param addr base address of the JNA-originated memory * @param length Length of ByteBuffer - * @return a direct ByteBuffer that accesses the memory being pointed to, + * @return a direct ByteBuffer that accesses the memory being pointed to + * @deprecated Use {@link Pointer#getByteBuffer(long, long)} (since 4.3.0) */ + @Deprecated public static native ByteBuffer getDirectByteBuffer(long addr, long length); + private static final ThreadLocal nativeThreadTerminationFlag = + new ThreadLocal() { + @Override + protected Memory initialValue() { + Memory m = new Memory(4); + m.clear(); + return m; + } + }; + private static final Map nativeThreads = Collections.synchronizedMap(new WeakHashMap()); + /**

      Indicate whether the JVM should detach the current native thread when the current Java code finishes execution. Generally this is used to avoid detaching native threads when it is known that a given thread @@ -2051,12 +2235,12 @@ // state every time. Clear the termination flag, since it's not // needed when the native thread is detached normally. nativeThreads.remove(thread); - Pointer p = (Pointer)nativeThreadTerminationFlag.get(); + Pointer p = nativeThreadTerminationFlag.get(); setDetachState(true, 0); } else { if (!nativeThreads.containsKey(thread)) { - Pointer p = (Pointer)nativeThreadTerminationFlag.get(); + Pointer p = nativeThreadTerminationFlag.get(); nativeThreads.put(thread, p); setDetachState(false, p.peer); } @@ -2064,25 +2248,13 @@ } static Pointer getTerminationFlag(Thread t) { - return (Pointer)nativeThreads.get(t); + return nativeThreads.get(t); } - private static Map nativeThreads = Collections.synchronizedMap(new WeakHashMap()); - - private static ThreadLocal nativeThreadTerminationFlag = - new ThreadLocal() { - @Override - protected Object initialValue() { - Memory m = new Memory(4); - m.clear(); - return m; - } - }; - private static native void setDetachState(boolean detach, long terminationFlag); private static class Buffers { - static boolean isBuffer(Class cls) { + static boolean isBuffer(Class cls) { return Buffer.class.isAssignableFrom(cls); } } diff -Nru libjna-java-4.2.2/src/com/sun/jna/NativeLibrary.java libjna-java-4.4.0/src/com/sun/jna/NativeLibrary.java --- libjna-java-4.2.2/src/com/sun/jna/NativeLibrary.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/NativeLibrary.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,15 +1,26 @@ /* Copyright (c) 2007 Wayne Meissner, All Rights Reserved * Copyright (c) 2007-2013 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

      - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; @@ -17,17 +28,18 @@ import java.io.BufferedReader; import java.io.File; import java.io.FilenameFilter; -import java.io.InputStreamReader; import java.io.IOException; -import java.lang.ref.WeakReference; +import java.io.InputStreamReader; import java.lang.ref.Reference; +import java.lang.ref.WeakReference; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; +import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -51,7 +63,7 @@ * with a name corresponding to that requested. Absolute paths to frameworks * are also accepted, either ending at the framework name (sans ".framework") * or the full path to the framework shared library - * (e.g. CoreServices.framework/CoreServices). + * (e.g. CoreServices.framework/CoreServices). *

    • Context class loader classpath. Deployed native libraries may be * installed on the classpath under * ${os-prefix}/LIBRARY_FILENAME, where ${os-prefix} @@ -70,14 +82,14 @@ private long handle; private final String libraryName; private final String libraryPath; - private final Map functions = new HashMap(); + private final Map functions = new HashMap(); final int callFlags; private String encoding; - final Map options; + final Map options; - private static final Map libraries = new HashMap(); - private static final Map searchPaths = Collections.synchronizedMap(new HashMap()); - private static final List librarySearchPath = new LinkedList(); + private static final Map> libraries = new HashMap>(); + private static final Map> searchPaths = Collections.synchronizedMap(new HashMap>()); + private static final List librarySearchPath = new ArrayList(); static { // Force initialization of native library @@ -89,13 +101,12 @@ return name + "|" + flags + "|" + encoding; } - private NativeLibrary(String libraryName, String libraryPath, long handle, Map options) { + private NativeLibrary(String libraryName, String libraryPath, long handle, Map options) { this.libraryName = getLibraryName(libraryName); this.libraryPath = libraryPath; this.handle = handle; Object option = options.get(Library.OPTION_CALLING_CONVENTION); - int callingConvention = option instanceof Number - ? ((Number)option).intValue() : Function.C_CONVENTION; + int callingConvention = option instanceof Number ? ((Number)option).intValue() : Function.C_CONVENTION; this.callFlags = callingConvention; this.options = options; this.encoding = (String)options.get(Library.OPTION_STRING_ENCODING); @@ -108,8 +119,14 @@ if (Platform.isWindows() && "kernel32".equals(this.libraryName.toLowerCase())) { synchronized(functions) { Function f = new Function(this, "GetLastError", Function.ALT_CONVENTION, encoding) { - Object invoke(Object[] args, Class returnType, boolean b) { - return new Integer(Native.getLastError()); + @Override + Object invoke(Object[] args, Class returnType, boolean b, int fixedArgs) { + return Integer.valueOf(Native.getLastError()); + } + + @Override + Object invoke(Method invokingMethod, Class[] paramTypes, Class returnType, Object[] inArgs, Map options) { + return Integer.valueOf(Native.getLastError()); } }; functions.put(functionKey("GetLastError", callFlags, encoding), f); @@ -118,7 +135,7 @@ } private static final int DEFAULT_OPEN_OPTIONS = -1; - private static int openFlags(Map options) { + private static int openFlags(Map options) { Object opt = options.get(Library.OPTION_OPEN_FLAGS); if (opt instanceof Number) { return ((Number)opt).intValue(); @@ -126,38 +143,39 @@ return DEFAULT_OPEN_OPTIONS; } - private static NativeLibrary loadLibrary(String libraryName, Map options) { - if (Native.DEBUG_LOAD) { - System.out.println("Looking for library '" + libraryName + "'"); - } + private static NativeLibrary loadLibrary(String libraryName, Map options) { + if (Native.DEBUG_LOAD) { + System.out.println("Looking for library '" + libraryName + "'"); + } boolean isAbsolutePath = new File(libraryName).isAbsolute(); - List searchPath = new LinkedList(); + List searchPath = new ArrayList(); int openFlags = openFlags(options); // Append web start path, if available. Note that this does not // attempt any library name variations String webstartPath = Native.getWebStartLibraryPath(libraryName); if (webstartPath != null) { - if (Native.DEBUG_LOAD) { - System.out.println("Adding web start path " + webstartPath); - } + if (Native.DEBUG_LOAD) { + System.out.println("Adding web start path " + webstartPath); + } searchPath.add(webstartPath); } // // Prepend any custom search paths specifically for this library // - List customPaths = (List) searchPaths.get(libraryName); + List customPaths = searchPaths.get(libraryName); if (customPaths != null) { synchronized (customPaths) { searchPath.addAll(0, customPaths); } } - if (Native.DEBUG_LOAD) { - System.out.println("Adding paths from jna.library.path: " + System.getProperty("jna.library.path")); - } + if (Native.DEBUG_LOAD) { + System.out.println("Adding paths from jna.library.path: " + System.getProperty("jna.library.path")); + } + searchPath.addAll(initPaths("jna.library.path")); String libraryPath = findLibraryPath(libraryName, searchPath); long handle = 0; @@ -167,92 +185,99 @@ // name if it cannot find the library. // try { - if (Native.DEBUG_LOAD) { - System.out.println("Trying " + libraryPath); - } + if (Native.DEBUG_LOAD) { + System.out.println("Trying " + libraryPath); + } handle = Native.open(libraryPath, openFlags); - } - catch(UnsatisfiedLinkError e) { + } catch(UnsatisfiedLinkError e) { // Add the system paths back for all fallback searching - if (Native.DEBUG_LOAD) { - System.out.println("Adding system paths: " + librarySearchPath); - } + if (Native.DEBUG_LOAD) { + System.out.println("Adding system paths: " + librarySearchPath); + } searchPath.addAll(librarySearchPath); } + try { if (handle == 0) { libraryPath = findLibraryPath(libraryName, searchPath); - if (Native.DEBUG_LOAD) { - System.out.println("Trying " + libraryPath); - } + if (Native.DEBUG_LOAD) { + System.out.println("Trying " + libraryPath); + } handle = Native.open(libraryPath, openFlags); if (handle == 0) { throw new UnsatisfiedLinkError("Failed to load library '" + libraryName + "'"); } } - } - catch(UnsatisfiedLinkError e) { - // For android, try to "preload" the library using + } catch(UnsatisfiedLinkError e) { + // For android, try to "preload" the library using // System.loadLibrary(), which looks into the private /data/data // path, not found in any properties if (Platform.isAndroid()) { try { - if (Native.DEBUG_LOAD) { - System.out.println("Preload (via System.loadLibrary) " + libraryName); - } + if (Native.DEBUG_LOAD) { + System.out.println("Preload (via System.loadLibrary) " + libraryName); + } System.loadLibrary(libraryName); handle = Native.open(libraryPath, openFlags); } - catch(UnsatisfiedLinkError e2) { e = e2; } + catch(UnsatisfiedLinkError e2) { + e = e2; + } } else if (Platform.isLinux() || Platform.isFreeBSD()) { // // Failed to load the library normally - try to match libfoo.so.* // - if (Native.DEBUG_LOAD) { - System.out.println("Looking for version variants"); - } + if (Native.DEBUG_LOAD) { + System.out.println("Looking for version variants"); + } libraryPath = matchLibrary(libraryName, searchPath); if (libraryPath != null) { - if (Native.DEBUG_LOAD) { - System.out.println("Trying " + libraryPath); - } - try { + if (Native.DEBUG_LOAD) { + System.out.println("Trying " + libraryPath); + } + try { handle = Native.open(libraryPath, openFlags); } - catch(UnsatisfiedLinkError e2) { e = e2; } + catch(UnsatisfiedLinkError e2) { + e = e2; + } } } // Search framework libraries on OS X - else if (Platform.isMac() - && !libraryName.endsWith(".dylib")) { - if (Native.DEBUG_LOAD) { - System.out.println("Looking for matching frameworks"); - } + else if (Platform.isMac() && !libraryName.endsWith(".dylib")) { + if (Native.DEBUG_LOAD) { + System.out.println("Looking for matching frameworks"); + } libraryPath = matchFramework(libraryName); if (libraryPath != null) { try { - if (Native.DEBUG_LOAD) { - System.out.println("Trying " + libraryPath); - } + if (Native.DEBUG_LOAD) { + System.out.println("Trying " + libraryPath); + } handle = Native.open(libraryPath, openFlags); } - catch(UnsatisfiedLinkError e2) { e = e2; } + catch(UnsatisfiedLinkError e2) { + e = e2; + } } } // Try the same library with a "lib" prefix else if (Platform.isWindows() && !isAbsolutePath) { - if (Native.DEBUG_LOAD) { - System.out.println("Looking for lib- prefix"); - } + if (Native.DEBUG_LOAD) { + System.out.println("Looking for lib- prefix"); + } libraryPath = findLibraryPath("lib" + libraryName, searchPath); - if (libraryPath != null) { - if (Native.DEBUG_LOAD) { - System.out.println("Trying " + libraryPath); - } - try { handle = Native.open(libraryPath, openFlags); } - catch(UnsatisfiedLinkError e2) { e = e2; } - } + if (libraryPath != null) { + if (Native.DEBUG_LOAD) { + System.out.println("Trying " + libraryPath); + } + try { + handle = Native.open(libraryPath, openFlags); + } catch(UnsatisfiedLinkError e2) { + e = e2; + } + } } // As a last resort, try to extract the library from the class // path, using the current context class loader. @@ -269,17 +294,19 @@ } } } - catch(IOException e2) { e = new UnsatisfiedLinkError(e2.getMessage()); } + catch(IOException e2) { + e = new UnsatisfiedLinkError(e2.getMessage()); + } } if (handle == 0) { - throw new UnsatisfiedLinkError("Unable to load library '" + libraryName + "': " - + e.getMessage()); + throw new UnsatisfiedLinkError("Unable to load library '" + libraryName + "': " + e.getMessage()); } } - if (Native.DEBUG_LOAD) { - System.out.println("Found library '" + libraryName + "' at " + libraryPath); - } + + if (Native.DEBUG_LOAD) { + System.out.println("Found library '" + libraryName + "' at " + libraryPath); + } return new NativeLibrary(libraryName, libraryPath, handle, options); } @@ -339,7 +366,7 @@ * the full path to the library (e.g. "/lib/libc.so.6"). */ public static final NativeLibrary getInstance(String libraryName) { - return getInstance(libraryName, Collections.EMPTY_MAP); + return getInstance(libraryName, Collections.emptyMap()); } /** @@ -359,9 +386,7 @@ * or as a plain file within the classpath. */ public static final NativeLibrary getInstance(String libraryName, ClassLoader classLoader) { - Map map = new HashMap(); - map.put(Library.OPTION_CLASSLOADER, classLoader); - return getInstance(libraryName, map); + return getInstance(libraryName, Collections.singletonMap(Library.OPTION_CLASSLOADER, classLoader)); } /** @@ -374,15 +399,14 @@ * @param libraryName The library name to load. * This can be short form (e.g. "c"), * an explicit version (e.g. "libc.so.6" or - * "QuickTime.framework/Versions/Current/QuickTime"), or - * the full (absolute) path to the library (e.g. "/lib/libc.so.6"). - * @param options native library options for the given library (see {@link - * Library}). + * "QuickTime.framework/Versions/Current/QuickTime"), or + * the full (absolute) path to the library (e.g. "/lib/libc.so.6"). + * @param libraryOptions Native library options for the given library (see {@link Library}). */ - public static final NativeLibrary getInstance(String libraryName, Map options) { - options = new HashMap(options); + public static final NativeLibrary getInstance(String libraryName, Map libraryOptions) { + Map options = new HashMap(libraryOptions); if (options.get(Library.OPTION_CALLING_CONVENTION) == null) { - options.put(Library.OPTION_CALLING_CONVENTION, new Integer(Function.C_CONVENTION)); + options.put(Library.OPTION_CALLING_CONVENTION, Integer.valueOf(Function.C_CONVENTION)); } // Use current process to load libraries we know are already @@ -392,8 +416,8 @@ libraryName = null; } synchronized (libraries) { - WeakReference ref = (WeakReference)libraries.get(libraryName + options); - NativeLibrary library = ref != null ? (NativeLibrary)ref.get() : null; + Reference ref = libraries.get(libraryName + options); + NativeLibrary library = (ref != null) ? ref.get() : null; if (library == null) { if (libraryName == null) { @@ -402,7 +426,7 @@ 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) { @@ -430,7 +454,7 @@ * mapped by some other mechanism, without having to reference or even * know the exact name of the native library. */ - public static synchronized final NativeLibrary getProcess(Map options) { + public static synchronized final NativeLibrary getProcess(Map options) { return getInstance(null, options); } @@ -444,15 +468,16 @@ */ public static final void addSearchPath(String libraryName, String path) { synchronized (searchPaths) { - List customPaths = (List) searchPaths.get(libraryName); + List customPaths = searchPaths.get(libraryName); if (customPaths == null) { - customPaths = Collections.synchronizedList(new LinkedList()); + customPaths = Collections.synchronizedList(new ArrayList()); searchPaths.put(libraryName, customPaths); } customPaths.add(path); } } + /** * Create a new {@link Function} that is linked with a native * function that follows the NativeLibrary's calling convention. @@ -460,8 +485,8 @@ *

      The allocated instance represents a pointer to the named native * function from the library. * - * @param functionName - * Name of the native function to be linked with + * @param functionName + * Name of the native function to be linked with * @throws UnsatisfiedLinkError if the function is not found */ public Function getFunction(String functionName) { @@ -475,17 +500,16 @@ *

      The allocated instance represents a pointer to the named native * function from the library. * - * @param name - * Name of the native function to be linked with. Uses a - * function mapper option if one was provided to - * transform the name. - * @param method - * Method to which the native function is to be mapped + * @param name + * Name of the native function to be linked with. Uses a + * function mapper option if one was provided to + * transform the name. + * @param method + * Method to which the native function is to be mapped * @throws UnsatisfiedLinkError if the function is not found */ Function getFunction(String name, Method method) { - FunctionMapper mapper = (FunctionMapper) - options.get(Library.OPTION_FUNCTION_MAPPER); + FunctionMapper mapper = (FunctionMapper) options.get(Library.OPTION_FUNCTION_MAPPER); if (mapper != null) { name = mapper.getFunctionName(this, method); } @@ -495,7 +519,7 @@ name = name.substring(prefix.length()); } int flags = this.callFlags; - Class[] etypes = method.getExceptionTypes(); + Class[] etypes = method.getExceptionTypes(); for (int i=0;i < etypes.length;i++) { if (LastErrorException.class.isAssignableFrom(etypes[i])) { flags |= Function.THROW_LAST_ERROR; @@ -508,10 +532,10 @@ * Create a new {@link Function} that is linked with a native * function that follows a given calling flags. * - * @param functionName - * Name of the native function to be linked with - * @param callFlags - * Flags affecting the function invocation + * @param functionName + * Name of the native function to be linked with + * @param callFlags + * Flags affecting the function invocation * @throws UnsatisfiedLinkError if the function is not found */ public Function getFunction(String functionName, int callFlags) { @@ -522,21 +546,22 @@ * Create a new {@link Function} that is linked with a native * function that follows a given calling flags. * - * @param functionName - * Name of the native function to be linked with - * @param callFlags - * Flags affecting the function invocation + * @param functionName + * Name of the native function to be linked with + * @param callFlags + * Flags affecting the function invocation * @param encoding * Encoding to use to convert between Java and native - * strings. + * strings. * @throws UnsatisfiedLinkError if the function is not found */ public Function getFunction(String functionName, int callFlags, String encoding) { - if (functionName == null) + if (functionName == null) { throw new NullPointerException("Function name may not be null"); + } synchronized (functions) { String key = functionKey(functionName, callFlags, encoding); - Function function = (Function) functions.get(key); + Function function = functions.get(key); if (function == null) { function = new Function(this, functionName, callFlags, encoding); functions.put(key, function); @@ -545,8 +570,8 @@ } } - /** Returns this native library instance's options. */ - public Map getOptions() { + /** @return this native library instance's options. */ + public Map getOptions() { return options; } @@ -558,11 +583,8 @@ public Pointer getGlobalVariableAddress(String symbolName) { try { return new Pointer(getSymbolAddress(symbolName)); - } - catch(UnsatisfiedLinkError e) { - throw new UnsatisfiedLinkError("Error looking up '" - + symbolName + "': " - + e.getMessage()); + } catch(UnsatisfiedLinkError e) { + throw new UnsatisfiedLinkError("Error looking up '" + symbolName + "': " + e.getMessage()); } } @@ -576,6 +598,8 @@ } return Native.findSymbol(handle, name); } + + @Override public String toString() { return "Native Library <" + libraryPath + "@" + handle + ">"; } @@ -593,19 +617,19 @@ return new File(libraryPath); } /** Close the library when it is no longer referenced. */ + @Override protected void finalize() { dispose(); } /** Close all open native libraries. */ static void disposeAll() { - Set values; + Set> values; synchronized(libraries) { - values = new HashSet(libraries.values()); + values = new LinkedHashSet>(libraries.values()); } - for (Iterator i=values.iterator();i.hasNext();) { - Reference ref = (WeakReference)i.next(); - NativeLibrary lib = (NativeLibrary)ref.get(); + for (Reference ref : values) { + NativeLibrary lib = ref.get(); if (lib != null) { lib.dispose(); } @@ -614,14 +638,20 @@ /** Close the native library we're mapped to. */ public void dispose() { + Set keys = new HashSet(); synchronized(libraries) { - for (Iterator i=libraries.values().iterator();i.hasNext();) { - Reference ref = (WeakReference)i.next(); + for (Map.Entry> e : libraries.entrySet()) { + Reference ref = e.getValue(); if (ref.get() == this) { - i.remove(); + keys.add(e.getKey()); } } + + for (String k : keys) { + libraries.remove(k); + } } + synchronized(this) { if (handle != 0) { Native.close(handle); @@ -630,13 +660,13 @@ } } - private static List initPaths(String key) { + private static List initPaths(String key) { String value = System.getProperty(key, ""); if ("".equals(value)) { - return Collections.EMPTY_LIST; + 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)) { @@ -647,7 +677,7 @@ } /** Use standard library search paths to find the library. */ - private static String findLibraryPath(String libName, List searchPath) { + private static String findLibraryPath(String libName, List searchPath) { // // If a full path to the library was specified, don't search for it @@ -662,8 +692,7 @@ String name = mapSharedLibraryName(libName); // Search in the JNA paths for it - for (Iterator it = searchPath.iterator(); it.hasNext(); ) { - String path = (String)it.next(); + for (String path : searchPath) { File file = new File(path, name); if (file.exists()) { return file.getAbsolutePath(); @@ -713,7 +742,7 @@ return libName; } } - else if (Platform.isAIX()) { // can be libx.a, libx.a(shr.o), libx.so + else if (Platform.isAIX()) { // can be libx.a, libx.a(shr.o), libx.so if (libName.startsWith("lib")) { return libName; } @@ -748,12 +777,13 @@ * where /usr/lib/libc.so does not exist, or it is not a valid symlink to * a versioned file (e.g. /lib/libc.so.6). */ - static String matchLibrary(final String libName, List searchPath) { - File lib = new File(libName); + static String matchLibrary(final String libName, List searchPath) { + File lib = new File(libName); if (lib.isAbsolute()) { - searchPath = Arrays.asList(new String[] { lib.getParent() }); + searchPath = Arrays.asList(lib.getParent()); } FilenameFilter filter = new FilenameFilter() { + @Override public boolean accept(File dir, String filename) { return (filename.startsWith("lib" + libName + ".so") || (filename.startsWith(libName + ".so") @@ -762,9 +792,9 @@ } }; - List matches = new LinkedList(); - for (Iterator it = searchPath.iterator(); it.hasNext(); ) { - File[] files = new File((String) it.next()).listFiles(filter); + Collection matches = new LinkedList(); + for (String path : searchPath) { + File[] files = new File(path).listFiles(filter); if (files != null && files.length > 0) { matches.addAll(Arrays.asList(files)); } @@ -775,8 +805,8 @@ // i.e. libc.so.6 is preferred over libc.so.5 double bestVersion = -1; String bestMatch = null; - for (Iterator it = matches.iterator(); it.hasNext(); ) { - String path = ((File) it.next()).getAbsolutePath(); + for (File f : matches) { + String path = f.getAbsolutePath(); String ver = path.substring(path.lastIndexOf(".so.") + 4); double version = parseVersion(ver); if (version > bestVersion) { @@ -788,10 +818,10 @@ } static double parseVersion(String ver) { - double v = 0; - double divisor = 1; - int dot = ver.indexOf("."); - while (ver != null) { + double v = 0; + double divisor = 1; + int dot = ver.indexOf("."); + while (ver != null) { String num; if (dot != -1) { num = ver.substring(0, dot); @@ -809,9 +839,9 @@ return 0; } divisor *= 100; - } + } - return v; + return v; } static { @@ -906,7 +936,7 @@ ? "-kfreebsd" : (Platform.isGNU() ? "" : "-linux"); String libc = "-gnu"; - + if (Platform.isIntel()) { cpu = (Platform.is64Bit() ? "x86_64" : "i386"); } @@ -917,7 +947,7 @@ cpu = "arm"; libc = "-gnueabi"; } - + return cpu + kernel + libc; } diff -Nru libjna-java-4.2.2/src/com/sun/jna/NativeLong.java libjna-java-4.4.0/src/com/sun/jna/NativeLong.java --- libjna-java-4.2.2/src/com/sun/jna/NativeLong.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/NativeLong.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Wayne Meissner, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

      - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; @@ -19,6 +30,7 @@ * @author wmeissner@gmail.com */ public class NativeLong extends IntegerType { + private static final long serialVersionUID = 1L; /** Size of a native long, in bytes. */ public static final int SIZE = Native.LONG_SIZE; @@ -26,7 +38,7 @@ public NativeLong() { this(0); } - + /** Create a NativeLong with the given value. */ public NativeLong(long value) { this(value, false); diff -Nru libjna-java-4.2.2/src/com/sun/jna/NativeMappedConverter.java libjna-java-4.4.0/src/com/sun/jna/NativeMappedConverter.java --- libjna-java-4.2.2/src/com/sun/jna/NativeMappedConverter.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/NativeMappedConverter.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; @@ -19,27 +30,27 @@ /** Provides type conversion for instances of {@link NativeMapped}. */ public class NativeMappedConverter implements TypeConverter { - private static final Map/*>*/ converters = new WeakHashMap(); - private final Class type; - private final Class nativeType; + private static final Map, Reference> converters = + new WeakHashMap, Reference>(); + private final Class type; + private final Class nativeType; private final NativeMapped instance; - public static NativeMappedConverter getInstance(Class cls) { + public static NativeMappedConverter getInstance(Class cls) { synchronized(converters) { - Reference r = (Reference)converters.get(cls); - NativeMappedConverter nmc = r != null ? (NativeMappedConverter)r.get() : null; + Reference r = converters.get(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; } } - public NativeMappedConverter(Class type) { + public NativeMappedConverter(Class type) { if (!NativeMapped.class.isAssignableFrom(type)) - throw new IllegalArgumentException("Type must derive from " - + NativeMapped.class); + throw new IllegalArgumentException("Type must derive from " + NativeMapped.class); this.type = type; this.instance = defaultValue(); this.nativeType = instance.nativeType(); @@ -48,26 +59,27 @@ public NativeMapped defaultValue() { try { return (NativeMapped)type.newInstance(); - } - catch (InstantiationException e) { + } catch (InstantiationException e) { String msg = "Can't create an instance of " + type + ", requires a no-arg constructor: " + e; throw new IllegalArgumentException(msg); - } - catch (IllegalAccessException e) { + } catch (IllegalAccessException e) { String msg = "Not allowed to create an instance of " + type + ", requires a public, no-arg constructor: " + e; throw new IllegalArgumentException(msg); } } + @Override public Object fromNative(Object nativeValue, FromNativeContext context) { return instance.fromNative(nativeValue, context); } - public Class nativeType() { + @Override + public Class nativeType() { return nativeType; } + @Override public Object toNative(Object value, ToNativeContext context) { if (value == null) { if (Pointer.class.isAssignableFrom(nativeType)) { diff -Nru libjna-java-4.2.2/src/com/sun/jna/NativeMapped.java libjna-java-4.4.0/src/com/sun/jna/NativeMapped.java --- libjna-java-4.2.2/src/com/sun/jna/NativeMapped.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/NativeMapped.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,27 +1,38 @@ /* Copyright (c) 2007 Wayne Meissner, 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; -/** Provide conversion for a Java type to and from a native type. +/** Provide conversion for a Java type to and from a native type. * {@link Function} and {@link Structure} will use this interface to determine * how to map a given Java object into a native type.

      * Implementations of this interface must provide a no-args constructor.

      *

      See {@link ToNativeConverter} for a list of allowable native types.

      - * @author wmeissner + * @author wmeissner */ public interface NativeMapped { /** Convert the given native object into its Java representation using - * the given context. + * the given context. * @param nativeValue Java representation of the native type to be converted. * @param context Context in which the conversion is taking place. * @return Converted object. @@ -34,5 +45,5 @@ /** Indicate the native type used by this converter. * @return Java class representation of the native type. */ - Class nativeType(); + Class nativeType(); } diff -Nru libjna-java-4.2.2/src/com/sun/jna/NativeString.java libjna-java-4.4.0/src/com/sun/jna/NativeString.java --- libjna-java-4.2.2/src/com/sun/jna/NativeString.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/NativeString.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,21 +1,32 @@ -/* This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

      - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. +/* 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.nio.CharBuffer; -/** Provides a temporary allocation of an immutable C string - * (const char* or const wchar_t*) for use when - * converting a Java String into a native memory function argument. +/** Provides a temporary allocation of an immutable C string + * (const char* or const wchar_t*) for use when + * converting a Java String into a native memory function argument. * * @author Todd Fast, todd.fast@sun.com * @author twall@users.sf.net @@ -29,6 +40,7 @@ private class StringMemory extends Memory { public StringMemory(long size) { super(size); } + @Override public String toString() { return NativeString.this.toString(); } @@ -44,8 +56,8 @@ /** Create a native string as a NUL-terminated array of wchar_t * (if wide is true) or char.

      * If not wide, the encoding is obtained from {@link - * Native#getDefaultStringEncoding()}. - * + * Native#getDefaultStringEncoding()}. + * * @param string value to write to native memory * @param wide whether to store the String as wchar_t */ @@ -54,7 +66,7 @@ } /** Create a native string as a NUL-terminated array of - * wchar_t. + * wchar_t. */ public NativeString(WString string) { this(string.toString(), WIDE_STRING); @@ -68,15 +80,14 @@ throw new NullPointerException("String must not be null"); } // Allocate the memory to hold the string. Note, we have to - // make this 1 element longer in order to accommodate the terminating + // make this 1 element longer in order to accommodate the terminating // NUL (which is generated in Pointer.setString()). this.encoding = encoding; - if (this.encoding == WIDE_STRING) { + if (WIDE_STRING.equals(this.encoding)) { int len = (string.length() + 1 ) * Native.WCHAR_SIZE; pointer = new StringMemory(len); pointer.setWideString(0, string); - } - else { + } else { byte[] data = Native.getBytes(string, encoding); pointer = new StringMemory(data.length + 1); pointer.write(0, data, 0, data.length); @@ -84,20 +95,22 @@ } } + @Override public int hashCode() { return toString().hashCode(); } + @Override public boolean equals(Object other) { - if (other instanceof CharSequence) { return compareTo(other) == 0; } return false; } + @Override public String toString() { - boolean wide = encoding == WIDE_STRING; + boolean wide = WIDE_STRING.equals(encoding); String s = wide ? "const wchar_t*" : "const char*"; s += "(" + (wide ? pointer.getWideString(0) : pointer.getString(0, encoding)) + ")"; return s; @@ -107,20 +120,23 @@ return pointer; } + @Override public char charAt(int index) { return toString().charAt(index); } + @Override public int length() { return toString().length(); } + @Override public CharSequence subSequence(int start, int end) { return CharBuffer.wrap(toString()).subSequence(start, end); } + @Override public int compareTo(Object other) { - if (other == null) return 1; diff -Nru libjna-java-4.2.2/src/com/sun/jna/Platform.java libjna-java-4.4.0/src/com/sun/jna/Platform.java --- libjna-java-4.2.2/src/com/sun/jna/Platform.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/Platform.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,32 @@ /* - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. This library is distributed in the - * hope that it will be useful, but WITHOUT ANY WARRANTY; without even - * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU Lesser General Public License for more details. + * 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.io.File; +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; + /** Provide simplified platform information. */ public final class Platform { public static final int UNSPECIFIED = -1; @@ -112,7 +130,7 @@ C_LIBRARY_NAME = osType == WINDOWS ? "msvcrt" : osType == WINDOWSCE ? "coredll" : "c"; MATH_LIBRARY_NAME = osType == WINDOWS ? "msvcrt" : osType == WINDOWSCE ? "coredll" : "m"; HAS_DLL_CALLBACKS = osType == WINDOWS; - ARCH = getCanonicalArchitecture(System.getProperty("os.arch")); + ARCH = getCanonicalArchitecture(System.getProperty("os.arch"), isSoftFloat()); RESOURCE_PREFIX = getNativeLibraryResourcePrefix(); } private Platform() { } @@ -207,7 +225,7 @@ return ARCH.startsWith("sparc"); } - static String getCanonicalArchitecture(String arch) { + static String getCanonicalArchitecture(String arch, boolean softfloat) { arch = arch.toLowerCase().trim(); if ("powerpc".equals(arch)) { arch = "ppc"; @@ -226,14 +244,37 @@ if ("ppc64".equals(arch) && "little".equals(System.getProperty("sun.cpu.endian"))) { arch = "ppc64le"; } + // Map arm to armel if the binary is running as softfloat build + if("arm".equals(arch) && softfloat) { + arch = "armel"; + } + + return arch; } + + private static boolean isSoftFloat() { + try { + File self = new File("/proc/self/exe"); + ELFAnalyser ahfd = ELFAnalyser.analyse(self.getCanonicalPath()); + return ahfd.isArmSoftFloat(); + } catch (IOException ex) { + // asume hardfloat + Logger.getLogger(Platform.class.getName()).log(Level.FINE, null, ex); + } + return false; + } /** Generate a canonical String prefix based on the current OS type/arch/name. */ static String getNativeLibraryResourcePrefix() { - return getNativeLibraryResourcePrefix(getOSType(), System.getProperty("os.arch"), System.getProperty("os.name")); + String prefix = System.getProperty("jna.prefix"); + if(prefix != null) { + return prefix; + } else { + return getNativeLibraryResourcePrefix(getOSType(), System.getProperty("os.arch"), System.getProperty("os.name")); + } } /** Generate a canonical String prefix based on the given OS @@ -243,8 +284,12 @@ @param name from os.name System property */ static String getNativeLibraryResourcePrefix(int osType, String arch, String name) { + return getNativeLibraryResourcePrefix(osType, arch, name, isSoftFloat()); + } + + static String getNativeLibraryResourcePrefix(int osType, String arch, String name, boolean isSoftfloat) { String osPrefix; - arch = getCanonicalArchitecture(arch); + arch = getCanonicalArchitecture(arch, isSoftfloat); switch(osType) { case Platform.ANDROID: if (arch.startsWith("arm")) { diff -Nru libjna-java-4.2.2/src/com/sun/jna/Pointer.java libjna-java-4.4.0/src/com/sun/jna/Pointer.java --- libjna-java-4.2.2/src/com/sun/jna/Pointer.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/Pointer.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,15 +1,28 @@ -/* This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

      - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. +/* 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.io.PrintWriter; +import java.io.StringWriter; import java.lang.reflect.Array; import java.nio.Buffer; import java.nio.ByteBuffer; @@ -18,13 +31,13 @@ import java.util.List; /** - * An abstraction for a native pointer data type. A Pointer instance - * represents, on the Java side, a native pointer. The native pointer could - * be any type of native pointer. Methods such as write, - * read, getXXX, and setXXX, provide + * An abstraction for a native pointer data type. A Pointer instance + * represents, on the Java side, a native pointer. The native pointer could + * be any type of native pointer. Methods such as write, + * read, getXXX, and setXXX, provide * means to access memory underlying the native pointer.

      * While a constructor exists to create a Pointer from an integer value, it's - * not generally a good idea to be creating pointers that way. + * not generally a good idea to be creating pointers that way. * * @author Sheng Liang, originator * @author Todd Fast, suitability modifications @@ -35,22 +48,22 @@ /** Size of a native pointer, in bytes. */ public static final int SIZE; - + static { // Force load of native library if ((SIZE = Native.POINTER_SIZE) == 0) { throw new Error("Native library not initialized"); } } - + /** Convenience constant, same as null. */ public static final Pointer NULL = null; - + /** Convenience constant, equivalent to (void*)CONSTANT. */ public static final Pointer createConstant(long peer) { return new Opaque(peer); } - + /** Convenience constant, equivalent to (void*)CONSTANT. This version will avoid setting any of the high bits on 64-bit systems. @@ -58,14 +71,16 @@ public static final Pointer createConstant(int peer) { return new Opaque((long)peer & 0xFFFFFFFF); } - - /** Pointer value of the real native pointer. Use long to be 64-bit safe. + + /** Pointer value of the real native pointer. Use long to be 64-bit safe. */ protected long peer; /** Derived class must assign peer pointer value. */ - Pointer() { } - + Pointer() { + super(); + } + /** Create from native pointer. Don't use this unless you know what * you're doing. */ @@ -77,12 +92,14 @@ public Pointer share(long offset) { return share(offset, 0); } - + /** Provide a view of this memory using the given offset to calculate a * new base address, bounds-limiting the memory with the given size. */ public Pointer share(long offset, long sz) { - if (offset == 0) return this; + if (offset == 0L) { + return this; + } return new Pointer(peer + offset); } @@ -91,27 +108,18 @@ setMemory(0, size, (byte)0); } - /** - * Compares this Pointer to the specified object. - * - * @param o - * A Pointer instance - * @return True if the other object is a Pointer, - * and the C pointers being pointed to by these objects are also - * equal. Returns false otherwise. - */ + @Override public boolean equals(Object o) { - if (o == this) return true; - if (o == null) return false; - return o instanceof Pointer && ((Pointer)o).peer == peer; + if (o == this) { + return true; + } + if (o == null) { + return false; + } + return (o instanceof Pointer) && (((Pointer)o).peer == peer); } - /** - * Returns a hashcode for the native pointer represented by this - * Pointer object - * - * @return A hash code value for the represented native pointer - */ + @Override public int hashCode() { return (int)((peer >>> 32) + (peer & 0xFFFFFFFF)); } @@ -125,9 +133,9 @@ * or -1 if the value is not found. */ public long indexOf(long offset, byte value) { - return Native.indexOf(peer + offset, value); + return Native.indexOf(this, this.peer, offset, value); } - + /** * Indirect the native pointer, copying from memory pointed to by * native pointer, into the specified array. @@ -138,7 +146,7 @@ * @param length number of elements from native pointer that must be copied */ public void read(long offset, byte[] buf, int index, int length) { - Native.read(peer + offset, buf, index, length); + Native.read(this, this.peer, offset, buf, index, length); } /** @@ -151,7 +159,7 @@ * @param length number of elements from native pointer that must be copied */ public void read(long offset, short[] buf, int index, int length) { - Native.read(peer + offset, buf, index, length); + Native.read(this, this.peer, offset, buf, index, length); } /** @@ -164,9 +172,9 @@ * @param length number of elements from native pointer that must be copied */ public void read(long offset, char[] buf, int index, int length) { - Native.read(peer + offset, buf, index, length); + Native.read(this, this.peer, offset, buf, index, length); } - + /** * Indirect the native pointer, copying from memory pointed to by * native pointer, into the specified array. @@ -177,7 +185,7 @@ * @param length number of elements from native pointer that must be copied */ public void read(long offset, int[] buf, int index, int length) { - Native.read(peer + offset, buf, index, length); + Native.read(this, this.peer, offset, buf, index, length); } /** @@ -190,7 +198,7 @@ * @param length number of elements from native pointer that must be copied */ public void read(long offset, long[] buf, int index, int length) { - Native.read(peer + offset, buf, index, length); + Native.read(this, this.peer, offset, buf, index, length); } /** @@ -203,7 +211,7 @@ * @param length number of elements from native pointer that must be copied */ public void read(long offset, float[] buf, int index, int length) { - Native.read(peer + offset, buf, index, length); + Native.read(this, this.peer, offset, buf, index, length); } /** @@ -216,7 +224,7 @@ * @param length number of elements from native pointer that must be copied */ public void read(long offset, double[] buf, int index, int length) { - Native.read(peer + offset, buf, index, length); + Native.read(this, this.peer, offset, buf, index, length); } /** @@ -255,7 +263,7 @@ * copied */ public void write(long offset, byte[] buf, int index, int length) { - Native.write(peer + offset, buf, index, length); + Native.write(this, this.peer, offset, buf, index, length); } /** @@ -269,7 +277,7 @@ * copied */ public void write(long offset, short[] buf, int index, int length) { - Native.write(peer + offset, buf, index, length); + Native.write(this, this.peer, offset, buf, index, length); } /** @@ -283,7 +291,7 @@ * copied */ public void write(long offset, char[] buf, int index, int length) { - Native.write(peer + offset, buf, index, length); + Native.write(this, this.peer, offset, buf, index, length); } /** @@ -297,11 +305,11 @@ * copied */ public void write(long offset, int[] buf, int index, int length) { - Native.write(peer + offset, buf, index, length); + Native.write(this, this.peer, offset, buf, index, length); } /** - * Indirect the native pointer, copying into memory pointed to by + * Indirect the native pointer, copying into memory pointed to by * native pointer, from the specified array. * * @param offset byte offset from pointer into which data is copied @@ -311,7 +319,7 @@ * copied */ public void write(long offset, long[] buf, int index, int length) { - Native.write(peer + offset, buf, index, length); + Native.write(this, this.peer, offset, buf, index, length); } /** @@ -325,7 +333,7 @@ * copied */ public void write(long offset, float[] buf, int index, int length) { - Native.write(peer + offset, buf, index, length); + Native.write(this, this.peer, offset, buf, index, length); } /** @@ -339,7 +347,7 @@ * copied */ public void write(long offset, double[] buf, int index, int length) { - Native.write(peer + offset, buf, index, length); + Native.write(this, this.peer, offset, buf, index, length); } /** Write the given array of Pointer to native memory. @@ -359,71 +367,58 @@ // Java type read methods ////////////////////////////////////////////////////////////////////////// - Object getValue(long offset, Class type, Object currentValue) { + Object getValue(long offset, Class type, Object currentValue) { Object result = null; if (Structure.class.isAssignableFrom(type)) { Structure s = (Structure)currentValue; if (Structure.ByReference.class.isAssignableFrom(type)) { s = Structure.updateStructureByReference(type, s, getPointer(offset)); - } - else { + } else { s.useMemory(this, (int)offset, true); s.read(); } result = s; - } - else if (type == boolean.class || type == Boolean.class) { + } else if (type == boolean.class || type == Boolean.class) { result = Function.valueOf(getInt(offset) != 0); - } - else if (type == byte.class || type == Byte.class) { - result = new Byte(getByte(offset)); - } - else if (type == short.class || type == Short.class) { - result = new Short(getShort(offset)); - } - else if (type == char.class || type == Character.class) { - result = new Character(getChar(offset)); - } - else if (type == int.class || type == Integer.class) { - result = new Integer(getInt(offset)); - } - else if (type == long.class || type == Long.class) { - result = new Long(getLong(offset)); - } - else if (type == float.class || type == Float.class) { - result=new Float(getFloat(offset)); - } - else if (type == double.class || type == Double.class) { - result = new Double(getDouble(offset)); - } - else if (Pointer.class.isAssignableFrom(type)) { + } else if (type == byte.class || type == Byte.class) { + result = Byte.valueOf(getByte(offset)); + } else if (type == short.class || type == Short.class) { + result = Short.valueOf(getShort(offset)); + } else if (type == char.class || type == Character.class) { + result = Character.valueOf(getChar(offset)); + } else if (type == int.class || type == Integer.class) { + result = Integer.valueOf(getInt(offset)); + } else if (type == long.class || type == Long.class) { + result = Long.valueOf(getLong(offset)); + } else if (type == float.class || type == Float.class) { + result = Float.valueOf(getFloat(offset)); + } else if (type == double.class || type == Double.class) { + result = Double.valueOf(getDouble(offset)); + } else if (Pointer.class.isAssignableFrom(type)) { Pointer p = getPointer(offset); if (p != null) { Pointer oldp = currentValue instanceof Pointer ? (Pointer)currentValue : null; - if (oldp == null || p.peer != oldp.peer) + if (oldp == null || p.peer != oldp.peer) { result = p; - else + } else { result = oldp; + } } - } - else if (type == String.class) { + } else if (type == String.class) { Pointer p = getPointer(offset); result = p != null ? p.getString(0) : null; - } - else if (type == WString.class) { + } else if (type == WString.class) { Pointer p = getPointer(offset); result = p != null ? new WString(p.getWideString(0)) : null; - } - else if (Callback.class.isAssignableFrom(type)) { + } else if (Callback.class.isAssignableFrom(type)) { // Overwrite the Java memory if the native pointer is a different // function pointer. Pointer fp = getPointer(offset); if (fp == null) { result = null; - } - else { + } else { Callback cb = (Callback)currentValue; Pointer oldfp = CallbackReference.getFunctionPointer(cb); if (!fp.equals(oldfp)) { @@ -431,13 +426,11 @@ } result = cb; } - } - else if (Platform.HAS_BUFFERS && Buffer.class.isAssignableFrom(type)) { + } else if (Platform.HAS_BUFFERS && Buffer.class.isAssignableFrom(type)) { Pointer bp = getPointer(offset); if (bp == null) { result = null; - } - else { + } else { Pointer oldbp = currentValue == null ? null : Native.getDirectBufferPointer((Buffer)currentValue); if (oldbp == null || !oldbp.equals(bp)) { @@ -445,8 +438,7 @@ } result = currentValue; } - } - else if (NativeMapped.class.isAssignableFrom(type)) { + } else if (NativeMapped.class.isAssignableFrom(type)) { NativeMapped nm = (NativeMapped)currentValue; if (nm != null) { Object value = getValue(offset, nm.nativeType(), null); @@ -454,33 +446,29 @@ if (nm.equals(result)) { result = nm; } - } - else { + } else { NativeMappedConverter tc = NativeMappedConverter.getInstance(type); Object value = getValue(offset, tc.nativeType(), null); result = tc.fromNative(value, new FromNativeContext(type)); } - } - else if (type.isArray()) { + } else if (type.isArray()) { result = currentValue; if (result == null) { throw new IllegalStateException("Need an initialized array"); } readArray(offset, result, type.getComponentType()); - } - else { - throw new IllegalArgumentException("Reading \"" - + type + "\" from memory is not supported"); + } else { + throw new IllegalArgumentException("Reading \"" + type + "\" from memory is not supported"); } return result; } /** Read memory starting at offset into the array with element type cls. */ - private void readArray(long offset, Object o, Class cls) { + private void readArray(long offset, Object o, Class cls) { int length = 0; length = Array.getLength(o); Object result = o; - + if (cls == byte.class) { read(offset, (byte[])result, 0, length); } @@ -562,7 +550,7 @@ * @return the byte value being pointed to */ public byte getByte(long offset) { - return Native.getByte(peer + offset); + return Native.getByte(this, this.peer, offset); } /** @@ -574,7 +562,7 @@ * @return the wchar_t value being pointed to */ public char getChar(long offset) { - return Native.getChar(peer + offset); + return Native.getChar(this, this.peer, offset); } /** @@ -586,7 +574,7 @@ * @return the short value being pointed to */ public short getShort(long offset) { - return Native.getShort(peer + offset); + return Native.getShort(this, this.peer, offset); } /** @@ -598,7 +586,7 @@ * @return the int value being pointed to */ public int getInt(long offset) { - return Native.getInt(peer + offset); + return Native.getInt(this, this.peer, offset); } /** @@ -610,7 +598,7 @@ * @return the long value being pointed to */ public long getLong(long offset) { - return Native.getLong(peer + offset); + return Native.getLong(this, this.peer, offset); } /** @@ -634,7 +622,7 @@ * @return the float value being pointed to */ public float getFloat(long offset) { - return Native.getFloat(peer + offset); + return Native.getFloat(this, this.peer, offset); } /** @@ -646,7 +634,7 @@ * @return the double value being pointed to */ public double getDouble(long offset) { - return Native.getDouble(peer + offset); + return Native.getDouble(this, this.peer, offset); } /** @@ -672,28 +660,29 @@ * @return a direct ByteBuffer that accesses the memory being pointed to, */ public ByteBuffer getByteBuffer(long offset, long length) { - return Native.getDirectByteBuffer(peer + offset, length).order(ByteOrder.nativeOrder()); + return Native.getDirectByteBuffer(this, this.peer, offset, length).order(ByteOrder.nativeOrder()); } /** * Copy native memory to a Java String. If wide is true, - * access the memory as an array of wchar_t, otherwise + * access the memory as an array of wchar_t, otherwise * as an array of char, using the default platform encoding. * * @param offset byte offset from pointer to obtain the native string v * @param wide whether to convert from a wide or standard C string - * @return the String value being pointed to - * + * @return the String value being pointed to + * * @deprecated use {@link #getString(long,String)} or {@link - * #getWideString(long)} instead. + * #getWideString(long)} instead. */ + @Deprecated public String getString(long offset, boolean wide) { return wide ? getWideString(offset) : getString(offset); } - + /** Read a wide (const wchar_t *) string from memory. */ public String getWideString(long offset) { - return Native.getWideString(peer + offset); + return Native.getWideString(this, this.peer, offset); } /** @@ -701,7 +690,7 @@ * form {@link Native#getDefaultStringEncoding()}. * * @param offset byte offset from pointer to start reading bytes - * @return the String value being pointed to + * @return the String value being pointed to */ public String getString(long offset) { return getString(offset, Native.getDefaultStringEncoding()); @@ -712,10 +701,10 @@ * * @param offset byte offset from pointer to obtain the native string * @param encoding the desired encoding - * @return the String value being pointed to + * @return the String value being pointed to */ public String getString(long offset, String encoding) { - return Native.getString(peer + offset, encoding); + return Native.getString(this, offset, encoding); } /** Read a native array of bytes of size arraySize from the @@ -726,7 +715,7 @@ read(offset, buf, 0, arraySize); return buf; } - + /** Read a native array of wchar_t of size arraySize from the given offset from this {@link Pointer}. */ @@ -785,7 +774,7 @@ * 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) { @@ -793,7 +782,7 @@ addOffset += Pointer.SIZE; p = getPointer(offset + addOffset); } - return (Pointer[])array.toArray(new Pointer[array.size()]); + return array.toArray(new Pointer[array.size()]); } /** Returns an array of {@link Pointer} of the requested size. */ @@ -805,7 +794,7 @@ /**

      Returns an array of String based on a native array * of char *. The array length is determined by a - * NULL-valued terminating element. + * NULL-valued terminating element. *

      * The strings are decoded using the encoding returned by {@link * Native#getDefaultStringEncoding()}. @@ -816,14 +805,14 @@ /** Returns an array of String based on a native array * of char *, using the requested encoding. The array length - * is determined by a NULL-valued terminating element. + * is determined by a NULL-valued terminating element. */ public String[] getStringArray(long offset, String encoding) { return getStringArray(offset, -1, encoding); } /**

      Returns an array of String based on a native array - * of char *, using the given array length. + * of char *, using the given array length. *

      * The strings are decoded using the encoding returned by {@link * Native#getDefaultStringEncoding()}. @@ -835,11 +824,12 @@ /** Returns an array of String based on a native array * of char* or wchar_t* based on the * wide parameter. The array length is determined by a - * NULL-valued terminating element. - * + * NULL-valued terminating element. + * * @deprecated use {@link #getStringArray(long,String)} or {@link * #getWideStringArray(long)} instead. */ + @Deprecated public String[] getStringArray(long offset, boolean wide) { return getStringArray(offset, -1, wide); } @@ -855,10 +845,11 @@ /** Returns an array of String based on a native array * of char* or wchar_t* based on the * wide parameter, using the given array length. - * + * * @deprecated use {@link #getStringArray(long,int,String)} or {@link * #getWideStringArray(long,int)} instead. */ + @Deprecated public String[] getStringArray(long offset, int length, boolean wide) { return getStringArray(offset, length, wide ? NativeString.WIDE_STRING : Native.getDefaultStringEncoding()); } @@ -871,7 +862,7 @@ * @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) { @@ -880,7 +871,7 @@ while (count++ < length) { String s = p == null ? null - : (encoding == NativeString.WIDE_STRING + : (NativeString.WIDE_STRING.equals(encoding) ? p.getWideString(0) : p.getString(0, encoding)); strings.add(s); if (count < length) { @@ -888,61 +879,49 @@ p = getPointer(offset + addOffset); } } - } - else { + } else { while ((p = getPointer(offset + addOffset)) != null) { String s = p == null ? null - : (encoding == NativeString.WIDE_STRING + : (NativeString.WIDE_STRING.equals(encoding) ? p.getWideString(0) : p.getString(0, encoding)); strings.add(s); addOffset += SIZE; } } - return (String[])strings.toArray(new String[strings.size()]); + return strings.toArray(new String[strings.size()]); } ////////////////////////////////////////////////////////////////////////// // Java type write methods ////////////////////////////////////////////////////////////////////////// - void setValue(long offset, Object value, Class type) { + void setValue(long offset, Object value, Class type) { // Set the value at the offset according to its type if (type == boolean.class || type == Boolean.class) { setInt(offset, Boolean.TRUE.equals(value) ? -1 : 0); - } - else if (type == byte.class || type == Byte.class) { + } else if (type == byte.class || type == Byte.class) { setByte(offset, value == null ? 0 : ((Byte)value).byteValue()); - } - else if (type == short.class || type == Short.class) { + } else if (type == short.class || type == Short.class) { setShort(offset, value == null ? 0 : ((Short)value).shortValue()); - } - else if (type == char.class || type == Character.class) { + } else if (type == char.class || type == Character.class) { setChar(offset, value == null ? 0 : ((Character)value).charValue()); - } - else if (type == int.class || type == Integer.class) { + } else if (type == int.class || type == Integer.class) { setInt(offset, value == null ? 0 : ((Integer)value).intValue()); - } - else if (type == long.class || type == Long.class) { + } else if (type == long.class || type == Long.class) { setLong(offset, value == null ? 0 : ((Long)value).longValue()); - } - else if (type == float.class || type == Float.class) { + } else if (type == float.class || type == Float.class) { setFloat(offset, value == null ? 0f : ((Float)value).floatValue()); - } - else if (type == double.class || type == Double.class) { + } else if (type == double.class || type == Double.class) { setDouble(offset, value == null ? 0.0 : ((Double)value).doubleValue()); - } - else if (type == Pointer.class) { + } else if (type == Pointer.class) { setPointer(offset, (Pointer)value); - } - else if (type == String.class) { + } else if (type == String.class) { setPointer(offset, (Pointer)value); - } - else if (type == WString.class) { + } else if (type == WString.class) { setPointer(offset, (Pointer)value); - } - else if (Structure.class.isAssignableFrom(type)) { + } else if (Structure.class.isAssignableFrom(type)) { Structure s = (Structure)value; if (Structure.ByReference.class.isAssignableFrom(type)) { setPointer(offset, s == null ? null : s.getPointer()); @@ -954,84 +933,68 @@ s.useMemory(this, (int)offset, true); s.write(); } - } - else if (Callback.class.isAssignableFrom(type)) { + } else if (Callback.class.isAssignableFrom(type)) { setPointer(offset, CallbackReference.getFunctionPointer((Callback)value)); - } - else if (Platform.HAS_BUFFERS && Buffer.class.isAssignableFrom(type)) { + } else if (Platform.HAS_BUFFERS && Buffer.class.isAssignableFrom(type)) { Pointer p = value == null ? null : Native.getDirectBufferPointer((Buffer)value); setPointer(offset, p); - } - else if (NativeMapped.class.isAssignableFrom(type)) { + } else if (NativeMapped.class.isAssignableFrom(type)) { NativeMappedConverter tc = NativeMappedConverter.getInstance(type); - Class nativeType = tc.nativeType(); + Class nativeType = tc.nativeType(); setValue(offset, tc.toNative(value, new ToNativeContext()), nativeType); - } - else if (type.isArray()) { + } else if (type.isArray()) { writeArray(offset, value, type.getComponentType()); - } - else { + } else { throw new IllegalArgumentException("Writing " + type + " to memory is not supported"); } } /** Write memory starting at offset from the array with element type cls. */ - private void writeArray(long offset, Object value, Class cls) { + private void writeArray(long offset, Object value, Class cls) { if (cls == byte.class) { byte[] buf = (byte[])value; write(offset, buf, 0, buf.length); - } - else if (cls == short.class) { + } else if (cls == short.class) { short[] buf = (short[])value; write(offset, buf, 0, buf.length); - } - else if (cls == char.class) { + } else if (cls == char.class) { char[] buf = (char[])value; write(offset, buf, 0, buf.length); - } - else if (cls == int.class) { + } else if (cls == int.class) { int[] buf = (int[])value; write(offset, buf, 0, buf.length); - } - else if (cls == long.class) { + } else if (cls == long.class) { long[] buf = (long[])value; write(offset, buf, 0, buf.length); - } - else if (cls == float.class) { + } else if (cls == float.class) { float[] buf = (float[])value; write(offset, buf, 0, buf.length); - } - else if (cls == double.class) { + } else if (cls == double.class) { double[] buf = (double[])value; write(offset, buf, 0, buf.length); - } - else if (Pointer.class.isAssignableFrom(cls)) { + } else if (Pointer.class.isAssignableFrom(cls)) { Pointer[] buf = (Pointer[])value; write(offset, buf, 0, buf.length); - } - else if (Structure.class.isAssignableFrom(cls)) { + } else if (Structure.class.isAssignableFrom(cls)) { Structure[] sbuf = (Structure[])value; if (Structure.ByReference.class.isAssignableFrom(cls)) { Pointer[] buf = new Pointer[sbuf.length]; for (int i=0;i < sbuf.length;i++) { if (sbuf[i] == null) { buf[i] = null; - } - else { + } else { buf[i] = sbuf[i].getPointer(); sbuf[i].write(); } } write(offset, buf, 0, buf.length); - } - else { + } else { Structure first = sbuf[0]; if (first == null) { first = Structure.newInstance(cls, share(offset)); sbuf[0] = first; - } - else { + } else { first.useMemory(this, (int)offset, true); } first.write(); @@ -1039,39 +1002,36 @@ for (int i=1;i < sbuf.length;i++) { if (sbuf[i] == null) { sbuf[i] = tmp[i]; - } - else { + } else { sbuf[i].useMemory(this, (int)(offset + i * sbuf[i].size()), true); } sbuf[i].write(); } } - } - else if (NativeMapped.class.isAssignableFrom(cls)) { + } else if (NativeMapped.class.isAssignableFrom(cls)) { NativeMapped[] buf = (NativeMapped[])value; NativeMappedConverter tc = NativeMappedConverter.getInstance(cls); - Class nativeType = tc.nativeType(); + Class nativeType = tc.nativeType(); int size = Native.getNativeSize(value.getClass(), value) / buf.length; for (int i=0;i < buf.length;i++) { Object element = tc.toNative(buf[i], new ToNativeContext()); setValue(offset + i*size, element, nativeType); } - } - else { + } else { throw new IllegalArgumentException("Writing array of " + cls + " to memory not supported"); } } - /** Write value to the requested bank of memory. + /** Write value to the requested bank of memory. * @param offset byte offset from pointer to start * @param length number of bytes to write * @param value value to be written */ public void setMemory(long offset, long length, byte value) { - Native.setMemory(peer + offset, length, value); + Native.setMemory(this, this.peer, offset, length, value); } - + /** * Set value at location being pointed to. This is equivalent * to the expression @@ -1082,7 +1042,7 @@ * @param value byte value to set */ public void setByte(long offset, byte value) { - Native.setByte(peer + offset, value); + Native.setByte(this, this.peer, offset, value); } /** @@ -1095,9 +1055,9 @@ * @param value short value to set */ public void setShort(long offset, short value) { - Native.setShort(peer + offset, value); + Native.setShort(this, this.peer, offset, value); } - + /** * Set value at location being pointed to. This is equivalent * to the expression @@ -1108,9 +1068,9 @@ * @param value char value to set */ public void setChar(long offset, char value) { - Native.setChar(peer + offset, value); + Native.setChar(this, this.peer, offset, value); } - + /** * Set value at location being pointed to. This is equivalent * to the expression @@ -1121,7 +1081,7 @@ * @param value int value to set */ public void setInt(long offset, int value) { - Native.setInt(peer + offset, value); + Native.setInt(this, this.peer, offset, value); } /** @@ -1134,9 +1094,9 @@ * @param value long value to set */ public void setLong(long offset, long value) { - Native.setLong(peer + offset, value); + Native.setLong(this, this.peer, offset, value); } - + /** * Set value at location being pointed to. This is equivalent * to the expression @@ -1164,9 +1124,9 @@ * @param value float value to set */ public void setFloat(long offset, float value) { - Native.setFloat(peer + offset, value); + Native.setFloat(this, this.peer, offset, value); } - + /** * Set value at location being pointed to. This is equivalent * to the expression @@ -1177,37 +1137,38 @@ * @param value double value to set */ public void setDouble(long offset, double value) { - Native.setDouble(peer + offset, value); + Native.setDouble(this, this.peer, offset, value); } /** * Set value at location being pointed to. This is equivalent - * to the expression + * to the expression * *((void **)((char *)Pointer + offset)) = value. * - * @param offset byte offset from pointer at which value + * @param offset byte offset from pointer at which value * must be set - * @param value Pointer holding the actual pointer value to + * @param value Pointer holding the actual pointer value to * set, which may be null to indicate a NULL * pointer. */ public void setPointer(long offset, Pointer value) { - Native.setPointer(peer + offset, value != null ? value.peer : 0); + Native.setPointer(this, this.peer, offset, value != null ? value.peer : 0); } /** - * Copy string value to the location being pointed to. + * Copy string value to the location being pointed to. * * @param offset byte offset from pointer at which characters in * value must be set * @param value java.lang.String value to set - * @param wide whether to write the native string as an array of - * wchar_t. If false, writes as a NUL-terminated array of + * @param wide whether to write the native string as an array of + * wchar_t. If false, writes as a NUL-terminated array of * char using the encoding indicated by {@link - * Native#getDefaultStringEncoding()}. - * + * Native#getDefaultStringEncoding()}. + * * @deprecated use {@link #setWideString(long,String)} instead. */ + @Deprecated public void setString(long offset, String value, boolean wide) { if (wide) { setWideString(offset, value); @@ -1216,22 +1177,22 @@ setString(offset, value); } } - + /** * Copy string value to the location being pointed to as a - * wide string (wchar_t*). + * wide string (wchar_t*). * * @param offset byte offset from pointer at which characters in * value must be set * @param value java.lang.String value to set */ public void setWideString(long offset, String value) { - Native.setWideString(peer + offset, value); + Native.setWideString(this, this.peer, offset, value); } /** * Copy string value to the location being pointed to as a - * wide string (wchar_t*). + * wide string (wchar_t*). * * @param offset byte offset from pointer at which characters in * value must be set @@ -1244,7 +1205,7 @@ /** * Copy bytes out of string value to the location being * pointed to, using the encoding indicated by {@link - * Native#getDefaultStringEncoding()}. + * Native#getDefaultStringEncoding()}. * * @param offset byte offset from pointer at which characters in * value must be set @@ -1256,7 +1217,7 @@ /** * Copy string value to the location being pointed to, using - * the requested encoding. + * the requested encoding. * * @param offset byte offset from pointer at which characters in * value must be set @@ -1268,31 +1229,37 @@ write(offset, data, 0, data.length); setByte(offset + data.length, (byte)0); } - + /** Dump memory for debugging purposes. */ public String dump(long offset, int size) { - String LS = System.getProperty("line.separator"); - String contents = "memory dump" + LS; final int BYTES_PER_ROW = 4; - byte[] buf = getByteArray(offset, size); - for (int i=0;i < buf.length;i++) { - if ((i % BYTES_PER_ROW) == 0) contents += "["; - if (buf[i] >=0 && buf[i] < 16) - contents += "0"; - contents += Integer.toHexString(buf[i] & 0xFF); - if ((i % BYTES_PER_ROW) == BYTES_PER_ROW-1 && i < buf.length-1) - contents += "]" + LS; + final String TITLE = "memory dump"; + // estimate initial size assuming a 2 char line separator + StringWriter sw = new StringWriter(TITLE.length() + 2 + size * 2 + (size / BYTES_PER_ROW * 4)); + PrintWriter out = new PrintWriter(sw); + out.println(TITLE); +// byte[] buf = getByteArray(offset, size); + for (int i=0;i < size;i++) { +// byte b = buf[i]; + byte b = getByte(offset + i); + if ((i % BYTES_PER_ROW) == 0) out.print("["); + if (b >=0 && b < 16) + out.print("0"); + out.print(Integer.toHexString(b & 0xFF)); + if ((i % BYTES_PER_ROW) == BYTES_PER_ROW-1 && i < size-1) + out.println("]"); } - if (!contents.endsWith("]" + LS)) { - contents += "]" + LS; + if (sw.getBuffer().charAt(sw.getBuffer().length() - 2) != ']') { + out.println("]"); } - return contents; + return sw.toString(); } + @Override public String toString() { return "native@0x" + Long.toHexString(peer); } - + /** Read the native peer value. Use with caution. */ public static long nativeValue(Pointer p) { return p == null ? 0 : p.peer; @@ -1307,129 +1274,175 @@ private static class Opaque extends Pointer { private Opaque(long peer) { super(peer); } private final String MSG = "This pointer is opaque: " + this; + @Override public Pointer share(long offset, long size) { throw new UnsupportedOperationException(MSG); } + @Override public void clear(long size) { throw new UnsupportedOperationException(MSG); } + @Override public long indexOf(long offset, byte value) { throw new UnsupportedOperationException(MSG); } - public void read(long bOff, byte[] buf, int index, int length) { - throw new UnsupportedOperationException(MSG); + @Override + public void read(long bOff, byte[] buf, int index, int length) { + throw new UnsupportedOperationException(MSG); } - public void read(long bOff, char[] buf, int index, int length) { - throw new UnsupportedOperationException(MSG); + @Override + public void read(long bOff, char[] buf, int index, int length) { + throw new UnsupportedOperationException(MSG); } - public void read(long bOff, short[] buf, int index, int length) { - throw new UnsupportedOperationException(MSG); + @Override + public void read(long bOff, short[] buf, int index, int length) { + throw new UnsupportedOperationException(MSG); } - public void read(long bOff, int[] buf, int index, int length) { - throw new UnsupportedOperationException(MSG); + @Override + public void read(long bOff, int[] buf, int index, int length) { + throw new UnsupportedOperationException(MSG); } - public void read(long bOff, long[] buf, int index, int length) { - throw new UnsupportedOperationException(MSG); + @Override + public void read(long bOff, long[] buf, int index, int length) { + throw new UnsupportedOperationException(MSG); } - public void read(long bOff, float[] buf, int index, int length) { - throw new UnsupportedOperationException(MSG); + @Override + public void read(long bOff, float[] buf, int index, int length) { + throw new UnsupportedOperationException(MSG); } - public void read(long bOff, double[] buf, int index, int length) { - throw new UnsupportedOperationException(MSG); + @Override + public void read(long bOff, double[] buf, int index, int length) { + throw new UnsupportedOperationException(MSG); } - public void read(long bOff, Pointer[] buf, int index, int length) { - throw new UnsupportedOperationException(MSG); + @Override + public void read(long bOff, Pointer[] buf, int index, int length) { + throw new UnsupportedOperationException(MSG); } - public void write(long bOff, byte[] buf, int index, int length) { - throw new UnsupportedOperationException(MSG); + @Override + public void write(long bOff, byte[] buf, int index, int length) { + throw new UnsupportedOperationException(MSG); } - public void write(long bOff, char[] buf, int index, int length) { - throw new UnsupportedOperationException(MSG); + @Override + public void write(long bOff, char[] buf, int index, int length) { + throw new UnsupportedOperationException(MSG); } - public void write(long bOff, short[] buf, int index, int length) { - throw new UnsupportedOperationException(MSG); + @Override + public void write(long bOff, short[] buf, int index, int length) { + throw new UnsupportedOperationException(MSG); } - public void write(long bOff, int[] buf, int index, int length) { - throw new UnsupportedOperationException(MSG); + @Override + public void write(long bOff, int[] buf, int index, int length) { + throw new UnsupportedOperationException(MSG); } - public void write(long bOff, long[] buf, int index, int length) { - throw new UnsupportedOperationException(MSG); + @Override + public void write(long bOff, long[] buf, int index, int length) { + throw new UnsupportedOperationException(MSG); } - public void write(long bOff, float[] buf, int index, int length) { - throw new UnsupportedOperationException(MSG); + @Override + public void write(long bOff, float[] buf, int index, int length) { + throw new UnsupportedOperationException(MSG); } - public void write(long bOff, double[] buf, int index, int length) { - throw new UnsupportedOperationException(MSG); + @Override + public void write(long bOff, double[] buf, int index, int length) { + throw new UnsupportedOperationException(MSG); } - public void write(long bOff, Pointer[] buf, int index, int length) { - throw new UnsupportedOperationException(MSG); + @Override + public void write(long bOff, Pointer[] buf, int index, int length) { + throw new UnsupportedOperationException(MSG); } + @Override public ByteBuffer getByteBuffer(long offset, long length) { - throw new UnsupportedOperationException(MSG); + throw new UnsupportedOperationException(MSG); } + @Override public byte getByte(long bOff) { - throw new UnsupportedOperationException(MSG); + throw new UnsupportedOperationException(MSG); } + @Override public char getChar(long bOff) { - throw new UnsupportedOperationException(MSG); + throw new UnsupportedOperationException(MSG); } + @Override public short getShort(long bOff) { - throw new UnsupportedOperationException(MSG); + throw new UnsupportedOperationException(MSG); } + @Override public int getInt(long bOff) { - throw new UnsupportedOperationException(MSG); + throw new UnsupportedOperationException(MSG); } + @Override public long getLong(long bOff) { - throw new UnsupportedOperationException(MSG); + throw new UnsupportedOperationException(MSG); } + @Override public float getFloat(long bOff) { - throw new UnsupportedOperationException(MSG); + throw new UnsupportedOperationException(MSG); } + @Override public double getDouble(long bOff) { - throw new UnsupportedOperationException(MSG); + throw new UnsupportedOperationException(MSG); } + @Override public Pointer getPointer(long bOff) { - throw new UnsupportedOperationException(MSG); + throw new UnsupportedOperationException(MSG); } + @Override public String getString(long bOff, String encoding) { - throw new UnsupportedOperationException(MSG); + throw new UnsupportedOperationException(MSG); } + @Override public String getWideString(long bOff) { - throw new UnsupportedOperationException(MSG); + throw new UnsupportedOperationException(MSG); } + @Override public void setByte(long bOff, byte value) { - throw new UnsupportedOperationException(MSG); + throw new UnsupportedOperationException(MSG); } + @Override public void setChar(long bOff, char value) { - throw new UnsupportedOperationException(MSG); + throw new UnsupportedOperationException(MSG); } + @Override public void setShort(long bOff, short value) { - throw new UnsupportedOperationException(MSG); + throw new UnsupportedOperationException(MSG); } + @Override public void setInt(long bOff, int value) { - throw new UnsupportedOperationException(MSG); + throw new UnsupportedOperationException(MSG); } + @Override public void setLong(long bOff, long value) { - throw new UnsupportedOperationException(MSG); + throw new UnsupportedOperationException(MSG); } + @Override public void setFloat(long bOff, float value) { - throw new UnsupportedOperationException(MSG); + throw new UnsupportedOperationException(MSG); } + @Override public void setDouble(long bOff, double value) { - throw new UnsupportedOperationException(MSG); + throw new UnsupportedOperationException(MSG); } + @Override public void setPointer(long offset, Pointer value) { - throw new UnsupportedOperationException(MSG); + throw new UnsupportedOperationException(MSG); } + @Override public void setString(long offset, String value, String encoding) { - throw new UnsupportedOperationException(MSG); + throw new UnsupportedOperationException(MSG); } + @Override public void setWideString(long offset, String value) { - throw new UnsupportedOperationException(MSG); + throw new UnsupportedOperationException(MSG); } + @Override public void setMemory(long offset, long size, byte value) { throw new UnsupportedOperationException(MSG); } + @Override + public String dump(long offset, int size) { + throw new UnsupportedOperationException(MSG); + } + @Override public String toString() { return "const@0x" + Long.toHexString(peer); } diff -Nru libjna-java-4.2.2/src/com/sun/jna/PointerType.java libjna-java-4.4.0/src/com/sun/jna/PointerType.java --- libjna-java-4.2.2/src/com/sun/jna/PointerType.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/PointerType.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,44 +1,56 @@ /* Copyright (c) 2007 Timothy Wall, 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; /** Type representing a type-safe native pointer. * Derived classes may override the {@link NativeMapped#fromNative} method, * which should instantiate a new object (or look up an existing one) - * of the appropriate type. + * of the appropriate type. */ public abstract class PointerType implements NativeMapped { private Pointer pointer; - + /** The default constructor wraps a NULL pointer. */ protected PointerType() { this.pointer = Pointer.NULL; } - + /** This constructor is typically used by {@link #fromNative} if generating - * a new object instance. + * a new object instance. */ protected PointerType(Pointer p) { this.pointer = p; } - /** All PointerType classes represent a native {@link Pointer}. - */ - public Class nativeType() { + /* All PointerType classes represent a native {@link Pointer}. */ + @Override + public Class nativeType() { return Pointer.class; } /** Convert this object to its native type (a {@link Pointer}). */ + @Override public Object toNative() { return getPointer(); } @@ -49,24 +61,25 @@ public Pointer getPointer() { return pointer; } - + public void setPointer(Pointer p) { this.pointer = p; } - + /** The default implementation simply creates a new instance of the class * and assigns its pointer field. Override if you need different behavior, * such as ensuring a single {@link PointerType} instance for each unique * {@link Pointer} value, or instantiating a different {@link PointerType} * subclass. */ + @Override public Object fromNative(Object nativeValue, FromNativeContext context) { // Always pass along null pointer values if (nativeValue == null) { return null; } try { - PointerType pt = (PointerType)getClass().newInstance(); + PointerType pt = getClass().newInstance(); pt.pointer = (Pointer)nativeValue; return pt; } @@ -81,24 +94,30 @@ /** The hash code for a PointerType is the same as that for * its pointer. */ + @Override public int hashCode() { return pointer != null ? pointer.hashCode() : 0; } - + /** Instances of PointerType with identical pointers compare * equal by default. */ + @Override public boolean equals(Object o) { - if (o == this) return true; + if (o == this) { + return true; + } if (o instanceof PointerType) { Pointer p = ((PointerType)o).getPointer(); - if (pointer == null) + if (pointer == null) { return p == null; + } return pointer.equals(p); } return false; } + @Override public String toString() { return pointer == null ? "NULL" : pointer.toString() + " (" + super.toString() + ")"; } diff -Nru libjna-java-4.2.2/src/com/sun/jna/ptr/ByReference.java libjna-java-4.4.0/src/com/sun/jna/ptr/ByReference.java --- libjna-java-4.2.2/src/com/sun/jna/ptr/ByReference.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/ptr/ByReference.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

      - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.ptr; diff -Nru libjna-java-4.2.2/src/com/sun/jna/ptr/ByteByReference.java libjna-java-4.4.0/src/com/sun/jna/ptr/ByteByReference.java --- libjna-java-4.2.2/src/com/sun/jna/ptr/ByteByReference.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/ptr/ByteByReference.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

      - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.ptr; diff -Nru libjna-java-4.2.2/src/com/sun/jna/ptr/DoubleByReference.java libjna-java-4.4.0/src/com/sun/jna/ptr/DoubleByReference.java --- libjna-java-4.2.2/src/com/sun/jna/ptr/DoubleByReference.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/ptr/DoubleByReference.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

      - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.ptr; diff -Nru libjna-java-4.2.2/src/com/sun/jna/ptr/FloatByReference.java libjna-java-4.4.0/src/com/sun/jna/ptr/FloatByReference.java --- libjna-java-4.2.2/src/com/sun/jna/ptr/FloatByReference.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/ptr/FloatByReference.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

      - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.ptr; diff -Nru libjna-java-4.2.2/src/com/sun/jna/ptr/IntByReference.java libjna-java-4.4.0/src/com/sun/jna/ptr/IntByReference.java --- libjna-java-4.2.2/src/com/sun/jna/ptr/IntByReference.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/ptr/IntByReference.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

      - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.ptr; diff -Nru libjna-java-4.2.2/src/com/sun/jna/ptr/LongByReference.java libjna-java-4.4.0/src/com/sun/jna/ptr/LongByReference.java --- libjna-java-4.2.2/src/com/sun/jna/ptr/LongByReference.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/ptr/LongByReference.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

      - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.ptr; diff -Nru libjna-java-4.2.2/src/com/sun/jna/ptr/NativeLongByReference.java libjna-java-4.4.0/src/com/sun/jna/ptr/NativeLongByReference.java --- libjna-java-4.2.2/src/com/sun/jna/ptr/NativeLongByReference.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/ptr/NativeLongByReference.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.ptr; diff -Nru libjna-java-4.2.2/src/com/sun/jna/ptr/PointerByReference.java libjna-java-4.4.0/src/com/sun/jna/ptr/PointerByReference.java --- libjna-java-4.2.2/src/com/sun/jna/ptr/PointerByReference.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/ptr/PointerByReference.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

      - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.ptr; diff -Nru libjna-java-4.2.2/src/com/sun/jna/ptr/ShortByReference.java libjna-java-4.4.0/src/com/sun/jna/ptr/ShortByReference.java --- libjna-java-4.2.2/src/com/sun/jna/ptr/ShortByReference.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/ptr/ShortByReference.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

      - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.ptr; diff -Nru libjna-java-4.2.2/src/com/sun/jna/StringArray.java libjna-java-4.4.0/src/com/sun/jna/StringArray.java --- libjna-java-4.2.2/src/com/sun/jna/StringArray.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/StringArray.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007-2008 Timothy Wall, 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

      - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; @@ -16,14 +27,14 @@ import java.util.Arrays; import java.util.List; -/** Handle native array of char* or wchar_t* type - * by managing allocation/disposal of native strings within an array of +/** Handle native array of char* or wchar_t* type + * by managing allocation/disposal of native strings within an array of * pointers. An extra NULL pointer is always added to the end of the native - * pointer array for convenience. + * pointer array for convenience. */ 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) { @@ -41,7 +52,7 @@ public StringArray(WString[] strings) { this(strings, NativeString.WIDE_STRING); } - private StringArray(Object[] strings, String encoding) { + private StringArray(Object[] strings, String encoding) { super((strings.length + 1) * Pointer.SIZE); this.original = strings; this.encoding = encoding; @@ -57,9 +68,10 @@ setPointer(Pointer.SIZE * strings.length, null); } /** Read back from native memory. */ + @Override public void read() { boolean returnWide = original instanceof WString[]; - boolean wide = encoding == NativeString.WIDE_STRING; + boolean wide = NativeString.WIDE_STRING.equals(encoding); for (int si=0;si < original.length;si++) { Pointer p = getPointer(si * Pointer.SIZE); Object s = null; @@ -71,8 +83,9 @@ } } + @Override public String toString() { - boolean wide = encoding == NativeString.WIDE_STRING; + boolean wide = NativeString.WIDE_STRING.equals(encoding); String s = wide ? "const wchar_t*[]" : "const char*[]"; s += Arrays.asList(original); return s; diff -Nru libjna-java-4.2.2/src/com/sun/jna/Structure.java libjna-java-4.4.0/src/com/sun/jna/Structure.java --- libjna-java-4.2.2/src/com/sun/jna/Structure.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/Structure.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007-2013 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

      - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; @@ -31,7 +42,6 @@ import java.util.Map; import java.util.Set; import java.util.WeakHashMap; -import java.util.zip.Adler32; /** * Represents a native structure with a Java peer class. When used as a @@ -123,8 +133,8 @@ //public static final int ALIGN_8 = 6; protected static final int CALCULATE_SIZE = -1; - static final Map layoutInfo = new WeakHashMap(); - static final Map fieldOrder = new WeakHashMap(); + static final Map, LayoutInfo> layoutInfo = new WeakHashMap, LayoutInfo>(); + static final Map, List> fieldOrder = new WeakHashMap, List>(); // This field is accessed by native code private Pointer memory; @@ -133,10 +143,10 @@ private String encoding; private int actualAlignType; private int structAlignment; - private Map structFields; + 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(); + private final Map nativeStrings = new HashMap(); private TypeMapper typeMapper; // This field is accessed by native code private long typeInfo; @@ -193,11 +203,11 @@ * calling this method. * @return {@link Map} of field names to field representations. */ - Map fields() { + Map fields() { return structFields; } - /** + /** * @return the type mapper in effect for this Structure. */ TypeMapper getTypeMapper() { @@ -270,7 +280,7 @@ /** * Obtain auto-allocated memory for use with struct represenations. - * @param size desired size + * @param size desired size * @return newly-allocated memory */ protected Memory autoAllocate(int size) { @@ -441,24 +451,26 @@ // Keep track of ByReference reads to avoid redundant reads of the same // address - private static final ThreadLocal reads = new ThreadLocal() { - protected synchronized Object initialValue() { - return new HashMap(); + private static final ThreadLocal> reads = new ThreadLocal>() { + @Override + protected synchronized Map initialValue() { + return new HashMap(); } }; // Keep track of what is currently being read/written to avoid redundant // reads (avoids problems with circular references). - private static final ThreadLocal busy = new ThreadLocal() { - protected synchronized Object initialValue() { + private static final ThreadLocal> busy = new ThreadLocal>() { + @Override + protected synchronized Set initialValue() { return new StructureSet(); } }; - + /** Avoid using a hash-based implementation since the hash code for a Structure is not immutable. */ - static class StructureSet extends AbstractCollection implements Set { + static class StructureSet extends AbstractCollection implements Set { Structure[] elements; private int count; private void ensureCapacity(int size) { @@ -474,19 +486,21 @@ public Structure[] getElements() { return elements; } + @Override public int size() { return count; } + @Override public boolean contains(Object o) { - return indexOf(o) != -1; + return indexOf((Structure) o) != -1; } - public boolean add(Object o) { + @Override + public boolean add(Structure o) { if (!contains(o)) { ensureCapacity(count+1); - elements[count++] = (Structure)o; + elements[count++] = o; } return true; } - private int indexOf(Object o) { - Structure s1 = (Structure)o; + private int indexOf(Structure s1) { for (int i=0;i < count;i++) { Structure s2 = elements[i]; if (s1 == s2 @@ -498,8 +512,9 @@ } return -1; } + @Override public boolean remove(Object o) { - int idx = indexOf(o); + int idx = indexOf((Structure) o); if (idx != -1) { if (--count >= 0) { elements[idx] = elements[count]; @@ -512,7 +527,8 @@ /** Simple implementation so that toString() doesn't break. Provides an iterator over a snapshot of this Set. */ - public Iterator iterator() { + @Override + public Iterator iterator() { Structure[] e = new Structure[count]; if (count > 0) { System.arraycopy(elements, 0, e, 0, count); @@ -520,12 +536,12 @@ return Arrays.asList(e).iterator(); } } - - static Set busy() { - return (Set)busy.get(); + + static Set busy() { + return busy.get(); } - static Map reading() { - return (Map)reads.get(); + static Map reading() { + return reads.get(); } /** Performs auto-read only if uninitialized. */ @@ -560,8 +576,7 @@ reading().put(getPointer(), this); } try { - for (Iterator i=fields().values().iterator();i.hasNext();) { - StructField structField = (StructField)i.next(); + for (StructField structField : fields().values()) { readField(structField); } } @@ -579,7 +594,7 @@ */ protected int fieldOffset(String name) { ensureAllocated(); - StructField f = (StructField)fields().get(name); + StructField f = fields().get(name); if (f == null) throw new IllegalArgumentException("No such field: " + name); return f.offset; @@ -593,7 +608,7 @@ */ public Object readField(String name) { ensureAllocated(); - StructField f = (StructField)fields().get(name); + StructField f = fields().get(name); if (f == null) throw new IllegalArgumentException("No such field: " + name); return readField(f); @@ -647,13 +662,13 @@ * @param address the native struct * * @return Updated Structure.ByReference object */ - static Structure updateStructureByReference(Class type, Structure s, Pointer address) { + static Structure updateStructureByReference(Class type, Structure s, Pointer address) { if (address == null) { s = null; } else { if (s == null || !address.equals(s.getPointer())) { - Structure s1 = (Structure)reading().get(address); + Structure s1 = reading().get(address); if (s1 != null && type.equals(s1.getClass())) { s = s1; s.autoRead(); @@ -682,7 +697,7 @@ int offset = structField.offset; // Determine the type of the field - Class fieldType = structField.type; + Class fieldType = structField.type; FromNativeConverter readConverter = structField.readConverter; if (readConverter != null) { fieldType = readConverter.nativeType(); @@ -748,8 +763,7 @@ busy().add(this); try { // Write all fields, except those marked 'volatile' - for (Iterator i=fields().values().iterator();i.hasNext();) { - StructField sf = (StructField)i.next(); + for (StructField sf : fields().values()) { if (!sf.isVolatile) { writeField(sf); } @@ -767,7 +781,7 @@ */ public void writeField(String name) { ensureAllocated(); - StructField f = (StructField)fields().get(name); + StructField f = fields().get(name); if (f == null) throw new IllegalArgumentException("No such field: " + name); writeField(f); @@ -782,7 +796,7 @@ */ public void writeField(String name, Object value) { ensureAllocated(); - StructField structField = (StructField)fields().get(name); + StructField structField = fields().get(name); if (structField == null) throw new IllegalArgumentException("No such field: " + name); setFieldValue(structField.field, value); @@ -804,7 +818,7 @@ Object value = getFieldValue(structField.field); // Determine the type of the field - Class fieldType = structField.type; + Class fieldType = structField.type; ToNativeConverter converter = structField.writeConverter; if (converter != null) { value = converter.toNative(value, new StructureWriteContext(this, structField.field)); @@ -824,7 +838,7 @@ return; } NativeString nativeString = wide - ? new NativeString(value.toString(), true) + ? new NativeString(value.toString(), true) : new NativeString(value.toString(), encoding); // Keep track of allocated C strings to avoid // premature garbage collection of the memory. @@ -874,7 +888,7 @@ * guaranteed to be predictable. * @return ordered list of field names */ - protected abstract List getFieldOrder(); + protected abstract List getFieldOrder(); /** * Force a compile-time error on the old method of field definition @@ -882,6 +896,7 @@ * @deprecated Use the required method getFieldOrder() instead to * indicate the order of fields in this structure. */ + @Deprecated protected final void setFieldOrder(String[] fields) { throw new Error("This method is obsolete, use getFieldOrder() instead"); } @@ -890,11 +905,11 @@ * @param fields list of fields to be sorted * @param names list of names representing the desired sort order */ - protected void sortFields(List fields, List names) { + protected void sortFields(List fields, List names) { for (int i=0;i < names.size();i++) { - String name = (String)names.get(i); + String name = names.get(i); for (int f=0;f < fields.size();f++) { - Field field = (Field)fields.get(f); + Field field = fields.get(f); if (name.equals(field.getName())) { Collections.swap(fields, i, f); break; @@ -907,18 +922,18 @@ * @return ordered list of public {@link java.lang.reflect.Field} available on * this {@link Structure} class. */ - protected List getFieldList() { - List flist = new ArrayList(); - for (Class cls = getClass(); + protected List getFieldList() { + List flist = new ArrayList(); + for (Class cls = getClass(); !cls.equals(Structure.class); cls = cls.getSuperclass()) { - List classFields = new ArrayList(); + 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)) + if (Modifier.isStatic(modifiers) || !Modifier.isPublic(modifiers)) { continue; + } classFields.add(fields[i]); } flist.addAll(0, classFields); @@ -929,19 +944,47 @@ /** Cache field order per-class. * @return (cached) ordered list of fields */ - private List fieldOrder() { + private List fieldOrder() { + Class clazz = getClass(); synchronized(fieldOrder) { - List list = (List)fieldOrder.get(getClass()); + List list = fieldOrder.get(clazz); if (list == null) { list = getFieldOrder(); - fieldOrder.put(getClass(), list); + fieldOrder.put(clazz, list); } return list; } } - private List sort(Collection c) { - List list = new ArrayList(c); + public static List createFieldsOrder(List baseFields, String ... extraFields) { + return createFieldsOrder(baseFields, Arrays.asList(extraFields)); + } + + public static List createFieldsOrder(List baseFields, List extraFields) { + List fields = new ArrayList(baseFields.size() + extraFields.size()); + fields.addAll(baseFields); + fields.addAll(extraFields); + return Collections.unmodifiableList(fields); + } + + /** + * @param field The (single) field name + * @return @return An un-modifiable list containing the field name + */ + public static List createFieldsOrder(String field) { + return Collections.unmodifiableList(Collections.singletonList(field)); + } + + /** + * @param fields The structure field names in correct order + * @return An un-modifiable list of the fields + */ + public static List createFieldsOrder(String ... fields) { + return Collections.unmodifiableList(Arrays.asList(fields)); + } + + private static > List sort(Collection c) { + List list = new ArrayList(c); Collections.sort(list); return list; } @@ -953,13 +996,14 @@ @throws Error if force is true and field order data not yet specified and can't be generated automatically. **/ - protected List getFields(boolean force) { - List flist = getFieldList(); - Set names = new HashSet(); - for (Iterator i=flist.iterator();i.hasNext();) { - names.add(((Field)i.next()).getName()); + protected List getFields(boolean force) { + List flist = getFieldList(); + Set names = new HashSet(); + for (Field f : flist) { + names.add(f.getName()); } - List fieldOrder = fieldOrder(); + + List fieldOrder = fieldOrder(); if (fieldOrder.size() != flist.size() && flist.size() > 1) { if (force) { throw new Error("Structure.getFieldOrder() on " + getClass() @@ -974,7 +1018,7 @@ 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 (" @@ -984,7 +1028,6 @@ } sortFields(flist, fieldOrder); - return flist; } @@ -1010,7 +1053,7 @@ * @param type Structure subclass to check * @return native size of the given Structure subclass */ - static int size(Class type) { + static int size(Class type) { return size(type, null); } @@ -1019,10 +1062,10 @@ * @param value optional instance of the given class * @return native size of the Structure subclass */ - static int size(Class type, Structure value) { + static int size(Class type, Structure value) { LayoutInfo info; synchronized(layoutInfo) { - info = (LayoutInfo)layoutInfo.get(type); + info = layoutInfo.get(type); } int sz = (info != null && !info.variable) ? info.size : CALCULATE_SIZE; if (sz == CALCULATE_SIZE) { @@ -1035,7 +1078,7 @@ } /** - * @param force whether to force size calculation. + * @param force whether to force size calculation. * @param avoidFFIType set false in certain situations to avoid recursive * type lookup. * @return calculated size, or {@link #CALCULATE_SIZE} if there is not yet @@ -1043,9 +1086,10 @@ */ int calculateSize(boolean force, boolean avoidFFIType) { int size = CALCULATE_SIZE; + Class clazz = getClass(); LayoutInfo info; synchronized(layoutInfo) { - info = (LayoutInfo)layoutInfo.get(getClass()); + info = layoutInfo.get(clazz); } if (info == null || this.alignType != info.alignType @@ -1063,10 +1107,10 @@ // type mapper; this way we don't override the cache // prematurely when processing subclasses that call // setAlignType() or setTypeMapper() in the constructor - if (!layoutInfo.containsKey(getClass()) + if (!layoutInfo.containsKey(clazz) || this.alignType != ALIGN_DEFAULT || this.typeMapper != null) { - layoutInfo.put(getClass(), info); + layoutInfo.put(clazz, info); } } } @@ -1081,7 +1125,7 @@ private static class LayoutInfo { private int size = CALCULATE_SIZE; private int alignment = 1; - private final Map fields = Collections.synchronizedMap(new LinkedHashMap()); + private final Map fields = Collections.synchronizedMap(new LinkedHashMap()); private int alignType = ALIGN_DEFAULT; private TypeMapper typeMapper; private boolean variable; @@ -1089,7 +1133,7 @@ private StructField typeInfoField; } - private void validateField(String name, Class type) { + private void validateField(String name, Class type) { if (typeMapper != null) { ToNativeConverter toNative = typeMapper.getToNativeConverter(type); if (toNative != null) { @@ -1113,9 +1157,8 @@ /** ensure all fields are of valid type. */ private void validateFields() { - List fields = getFieldList(); - for (Iterator i=fields.iterator();i.hasNext();) { - Field f = (Field)i.next(); + List fields = getFieldList(); + for (Field f : fields) { validateField(f.getName(), f.getType()); } } @@ -1126,7 +1169,7 @@ */ private LayoutInfo deriveLayout(boolean force, boolean avoidFFIType) { int calculatedSize = 0; - List fields = getFields(force); + List fields = getFields(force); if (fields == null) { return null; } @@ -1136,11 +1179,11 @@ info.typeMapper = this.typeMapper; boolean firstField = true; - for (Iterator i=fields.iterator();i.hasNext();firstField=false) { - Field field = (Field)i.next(); + for (Iterator i=fields.iterator();i.hasNext();firstField=false) { + Field field = i.next(); int modifiers = field.getModifiers(); - Class type = field.getType(); + Class type = field.getType(); if (type.isArray()) { info.variable = true; } @@ -1187,7 +1230,7 @@ // can't calculate size yet, defer until later return null; } - Class nativeType = type; + Class nativeType = type; if (NativeMapped.class.isAssignableFrom(type)) { NativeMappedConverter tc = NativeMappedConverter.getInstance(type); nativeType = tc.nativeType(); @@ -1278,9 +1321,8 @@ */ private void initializeFields() { // Get the full field list, don't care about sorting - List flist = getFieldList(); - for (Iterator i = flist.iterator(); i.hasNext();) { - Field f = (Field) i.next(); + List flist = getFieldList(); + for (Field f : flist) { try { Object o = f.get(this); if (o == null) { @@ -1293,7 +1335,7 @@ } } - private Object initializeField(Field field, Class type) { + private Object initializeField(Field field, Class type) { Object value = null; if (Structure.class.isAssignableFrom(type) && !(ByReference.class.isAssignableFrom(type))) { @@ -1345,12 +1387,12 @@ * @param type field type * @param value field value, if available * @param isFirstElement is this field the first element in the struct? - * @return the native byte alignment + * @return the native byte alignment */ // TODO: write getNaturalAlignment(stack/alloc) + getEmbeddedAlignment(structs) // TODO: move this into a native call which detects default alignment // automatically - protected int getNativeAlignment(Class type, Object value, boolean isFirstElement) { + protected int getNativeAlignment(Class type, Object value, boolean isFirstElement) { int alignment = 1; if (NativeMapped.class.isAssignableFrom(type)) { NativeMappedConverter tc = NativeMappedConverter.getInstance(type); @@ -1407,25 +1449,26 @@ return alignment; } - /** + /** * If jna.dump_memory is true, will include a native memory dump * of the Structure's backing memory. - * @return String representation of this object. + * @return String representation of this object. */ + @Override public String toString() { return toString(Boolean.getBoolean("jna.dump_memory")); } /** * @param debug If true, will include a native memory dump of the - * Structure's backing memory. + * Structure's backing memory. * @return String representation of this object. */ public String toString(boolean debug) { return toString(0, true, debug); } - private String format(Class type) { + private String format(Class type) { String s = type.getName(); int dot = s.lastIndexOf("."); return s.substring(dot + 1); @@ -1446,8 +1489,8 @@ if (!showContents) { contents = "...}"; } - else for (Iterator i=fields().values().iterator();i.hasNext();) { - StructField sf = (StructField)i.next(); + else for (Iterator i = fields().values().iterator(); i.hasNext();) { + StructField sf = i.next(); Object value = getFieldValue(sf.field); String type = format(sf.type); String index = ""; @@ -1545,7 +1588,7 @@ return toArray((Structure[])Array.newInstance(getClass(), size)); } - private Class baseClass() { + private Class baseClass() { if ((this instanceof Structure.ByReference || this instanceof Structure.ByValue) && Structure.class.isAssignableFrom(getClass().getSuperclass())) { @@ -1560,11 +1603,11 @@ * @return equality result */ public boolean dataEquals(Structure s) { - return dataEquals(s, false); + return dataEquals(s, false); } /** Return whether the given Structure's backing data is identical to - * this one, optionally clearing and re-writing native memory before checking. + * this one, optionally clearing and re-writing native memory before checking. * @param s Structure to compare * @param clear whether to clear native memory * @return equality result @@ -1589,18 +1632,20 @@ return false; } - /** + /** * @return whether the given structure's type and pointer match. */ + @Override public boolean equals(Object o) { return o instanceof Structure && o.getClass() == getClass() && ((Structure)o).getPointer().equals(getPointer()); } - /** + /** * @return hash code for this structure's pointer. */ + @Override public int hashCode() { Pointer p = getPointer(); if (p != null) { @@ -1621,7 +1666,7 @@ * @return Native pointer to the corresponding type information */ Pointer getFieldTypeInfo(StructField f) { - Class type = f.type; + Class type = f.type; Object value = getFieldValue(f.field); if (typeMapper != null) { ToNativeConverter nc = typeMapper.getToNativeConverter(type); @@ -1633,7 +1678,7 @@ return FFIType.get(value, type); } - /** + /** * @return native type information for this structure. */ Pointer getTypeInfo() { @@ -1667,7 +1712,7 @@ setAutoWrite(auto); } - /** Set whether the structure is read from native memory prior to + /** Set whether the structure is read from native memory after * a native function call. * @param auto whether to automatically synch from native memory. */ @@ -1675,7 +1720,7 @@ this.autoRead = auto; } - /** Returns whether the structure is read from native memory prior to + /** Returns whether the structure is read from native memory after * a native function call. * @return whether automatic synch from native memory is enabled. */ @@ -1683,7 +1728,7 @@ return this.autoRead; } - /** Set whether the structure is written to native memory after a native + /** Set whether the structure is written to native memory prior to a native * function call. * @param auto whether to automatically synch to native memory. */ @@ -1691,7 +1736,7 @@ this.autoWrite = auto; } - /** Returns whether the structure is written to native memory after a native + /** Returns whether the structure is written to native memory prior to a native * function call. * @return whether automatic synch to native memory is enabled. */ @@ -1711,7 +1756,7 @@ * #newInstance(Class,Pointer)}, except that it additionally calls * {@link #conditionalAutoRead()}. */ - private static Structure newInstance(Class type, long init) { + private static Structure newInstance(Class type, long init) { try { Structure s = newInstance(type, init == 0 ? PLACEHOLDER_MEMORY : new Pointer(init)); if (init != 0) { @@ -1732,10 +1777,10 @@ * @return the new instance * @throws IllegalArgumentException if the instantiation fails */ - public static Structure newInstance(Class type, Pointer init) throws IllegalArgumentException { + public static Structure newInstance(Class type, Pointer init) throws IllegalArgumentException { try { - Constructor ctor = type.getConstructor(new Class[] { Pointer.class }); - return (Structure)ctor.newInstance(new Object[] { init }); + Constructor ctor = type.getConstructor(Pointer.class); + return (Structure)ctor.newInstance(init); } catch(NoSuchMethodException e) { // Not defined, fall back to the default @@ -1768,7 +1813,7 @@ * @return the new instance * @throws IllegalArgumentException if the instantiation fails */ - public static Structure newInstance(Class type) throws IllegalArgumentException { + public static Structure newInstance(Class type) throws IllegalArgumentException { try { Structure s = (Structure)type.newInstance(); if (s instanceof ByValue) { @@ -1794,7 +1839,7 @@ StructField typeInfoField() { LayoutInfo info; synchronized(layoutInfo) { - info = (LayoutInfo)layoutInfo.get(getClass()); + info = layoutInfo.get(getClass()); } if (info != null) { return info.typeInfoField; @@ -1804,7 +1849,7 @@ protected static class StructField extends Object { public String name; - public Class type; + public Class type; public Field field; public int size = -1; public int offset = -1; @@ -1813,6 +1858,7 @@ public FromNativeConverter readConverter; public ToNativeConverter writeConverter; public FromNativeContext context; + @Override public String toString() { return name + "@" + offset + "[" + size + "] (" + type + ")"; } @@ -1823,10 +1869,14 @@ */ static class FFIType extends Structure { public static class size_t extends IntegerType { + private static final long serialVersionUID = 1L; + public size_t() { this(0); } public size_t(long value) { super(Native.SIZE_T_SIZE, value); } } - private static Map typeInfoMap = new WeakHashMap(); + + private static final Map typeInfoMap = new WeakHashMap(); + // Native.initIDs initializes these fields to their appropriate // pointer values. These are in a separate class from FFIType so that // they may be initialized prior to loading the FFIType class @@ -1845,6 +1895,7 @@ private static Pointer ffi_type_sint64; private static Pointer ffi_type_pointer; } + static { if (Native.POINTER_SIZE == 0) throw new Error("Native library not initialized"); @@ -1896,15 +1947,14 @@ else { els = new Pointer[ref.fields().size() + 1]; int idx = 0; - for (Iterator i=ref.fields().values().iterator();i.hasNext();) { - StructField sf = (StructField)i.next(); + for (StructField sf : ref.fields().values()) { els[idx++] = ref.getFieldTypeInfo(sf); } } init(els); } // Represent fixed-size arrays as structures of N identical elements - private FFIType(Object array, Class type) { + private FFIType(Object array, Class type) { int length = Array.getLength(array); Pointer[] els = new Pointer[length+1]; Pointer p = get(null, type.getComponentType()); @@ -1913,7 +1963,9 @@ } init(els); } - protected List getFieldOrder() { + + @Override + protected List getFieldOrder() { return Arrays.asList(new String[] { "size", "alignment", "type", "elements" }); } private void init(Pointer[] els) { @@ -1927,11 +1979,11 @@ if (obj == null) return FFITypes.ffi_type_pointer; if (obj instanceof Class) - return get(null, (Class)obj); + return get(null, (Class)obj); return get(obj, obj.getClass()); } - private static Pointer get(Object obj, Class cls) { + private static Pointer get(Object obj, Class cls) { TypeMapper mapper = Native.getTypeMapper(cls); if (mapper != null) { ToNativeConverter nc = mapper.getToNativeConverter(cls); @@ -1983,6 +2035,7 @@ // Always clear new structure memory super.clear(); } + @Override public String toString() { return "auto-" + super.toString(); } @@ -2058,7 +2111,7 @@ * @param nativeType field type to examine * @return native size (in bytes) of the requested field type */ - protected int getNativeSize(Class nativeType) { + protected int getNativeSize(Class nativeType) { return getNativeSize(nativeType, null); } @@ -2068,7 +2121,7 @@ * @param value instance of the field type * @return native size (in bytes) of the requested field type */ - protected int getNativeSize(Class nativeType, Object value) { + protected int getNativeSize(Class nativeType, Object value) { return Native.getNativeSize(nativeType, value); } @@ -2076,13 +2129,14 @@ * Structure needs a valid pointer but want to avoid actually reading from it. */ private static final Pointer PLACEHOLDER_MEMORY = new Pointer(0) { + @Override public Pointer share(long offset, long sz) { return this; } }; /** Indicate whether the given Structure class can be created by JNA. * @param cls Structure subclass to check */ - static void validate(Class cls) { + static void validate(Class cls) { Structure.newInstance(cls, PLACEHOLDER_MEMORY); } } diff -Nru libjna-java-4.2.2/src/com/sun/jna/StructureReadContext.java libjna-java-4.4.0/src/com/sun/jna/StructureReadContext.java --- libjna-java-4.2.2/src/com/sun/jna/StructureReadContext.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/StructureReadContext.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; diff -Nru libjna-java-4.2.2/src/com/sun/jna/StructureWriteContext.java libjna-java-4.4.0/src/com/sun/jna/StructureWriteContext.java --- libjna-java-4.2.2/src/com/sun/jna/StructureWriteContext.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/StructureWriteContext.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Wayne Meissner, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; diff -Nru libjna-java-4.2.2/src/com/sun/jna/ToNativeContext.java libjna-java-4.4.0/src/com/sun/jna/ToNativeContext.java --- libjna-java-4.2.2/src/com/sun/jna/ToNativeContext.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/ToNativeContext.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Wayne Meissner, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; diff -Nru libjna-java-4.2.2/src/com/sun/jna/ToNativeConverter.java libjna-java-4.4.0/src/com/sun/jna/ToNativeConverter.java --- libjna-java-4.2.2/src/com/sun/jna/ToNativeConverter.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/ToNativeConverter.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,13 +1,26 @@ /* - * Copyright (c) 2007 Wayne Meissner, All Rights Reserved This library - * is free software; you can redistribute it and/or modify it under the - * terms of the GNU Lesser General Public License as published by the - * Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version.

      This library is distributed in - * the hope that it will be useful, but WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR A - * PARTICULAR PURPOSE. See the GNU Lesser General Public License for - * more details. + * Copyright (c) 2007 Wayne Meissner, 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; @@ -38,5 +51,5 @@ */ Object toNative(Object value, ToNativeContext context); /** Indicate the type expected from {@link #toNative}. */ - Class nativeType(); + Class nativeType(); } diff -Nru libjna-java-4.2.2/src/com/sun/jna/TypeConverter.java libjna-java-4.4.0/src/com/sun/jna/TypeConverter.java --- libjna-java-4.2.2/src/com/sun/jna/TypeConverter.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/TypeConverter.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; diff -Nru libjna-java-4.2.2/src/com/sun/jna/TypeMapper.java libjna-java-4.4.0/src/com/sun/jna/TypeMapper.java --- libjna-java-4.2.2/src/com/sun/jna/TypeMapper.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/TypeMapper.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,28 +1,39 @@ /* Copyright (c) 2007 Timothy Wall, 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; /** Provides converters for conversion to and from native types. */ public interface TypeMapper { - /** Return the {@link FromNativeConverter} appropriate for the given Java class. + /** Return the {@link FromNativeConverter} appropriate for the given Java class. * @param javaType Java class representation of the native type. * @return Converter from the native-compatible type. */ - FromNativeConverter getFromNativeConverter(Class javaType); + FromNativeConverter getFromNativeConverter(Class javaType); - /** Return the {@link ToNativeConverter} appropriate for the given Java class. + /** Return the {@link ToNativeConverter} appropriate for the given Java class. * @param javaType Java class representation of the native type. * @return Converter to the native-compatible type. */ - ToNativeConverter getToNativeConverter(Class javaType); + ToNativeConverter getToNativeConverter(Class javaType); } diff -Nru libjna-java-4.2.2/src/com/sun/jna/Union.java libjna-java-4.4.0/src/com/sun/jna/Union.java --- libjna-java-4.2.2/src/com/sun/jna/Union.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/Union.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,20 +1,30 @@ /* Copyright (c) 2007-2012 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.lang.reflect.Field; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; /** Represents a native union. When writing to native memory, the field @@ -54,11 +64,11 @@ /** Unions do not need a field order, so automatically provide a value to * satisfy checking in the Structure superclass. */ - protected List getFieldOrder() { - List flist = getFieldList(); - ArrayList list = new ArrayList(); - for (Iterator i=flist.iterator();i.hasNext();) { - Field f = (Field)i.next(); + @Override + protected List getFieldOrder() { + List flist = getFieldList(); + List list = new ArrayList(flist.size()); + for (Field f : flist) { list.add(f.getName()); } return list; @@ -71,10 +81,9 @@ * @throws IllegalArgumentException if the type does not correspond to * any declared union field. */ - public void setType(Class type) { + public void setType(Class type) { ensureAllocated(); - for (Iterator i=fields().values().iterator();i.hasNext();) { - StructField f = (StructField)i.next(); + for (StructField f : fields().values()) { if (f.type == type) { activeField = f; return; @@ -91,7 +100,7 @@ */ public void setType(String fieldName) { ensureAllocated(); - StructField f = (StructField) fields().get(fieldName); + StructField f = fields().get(fieldName); if (f != null) { activeField = f; } @@ -105,6 +114,7 @@ * @return the new field value, after updating * @throws IllegalArgumentException if no field exists with the given name */ + @Override public Object readField(String fieldName) { ensureAllocated(); setType(fieldName); @@ -115,6 +125,7 @@ * The given field will become the active one. * @throws IllegalArgumentException if no field exists with the given name */ + @Override public void writeField(String fieldName) { ensureAllocated(); setType(fieldName); @@ -125,6 +136,7 @@ * The given field will become the active one. * @throws IllegalArgumentException if no field exists with the given name */ + @Override public void writeField(String fieldName, Object value) { ensureAllocated(); setType(fieldName); @@ -143,10 +155,9 @@ * @param type class type of the Structure field to read * @return the Structure field with the given type */ - public Object getTypedValue(Class type) { + public Object getTypedValue(Class type) { ensureAllocated(); - for (Iterator i=fields().values().iterator();i.hasNext();) { - StructField f = (StructField)i.next(); + for (StructField f : fields().values()) { if (f.type == type) { activeField = f; read(); @@ -181,10 +192,9 @@ * @param type type to search for * @return StructField of matching type */ - private StructField findField(Class type) { + private StructField findField(Class type) { ensureAllocated(); - for (Iterator i=fields().values().iterator();i.hasNext();) { - StructField f = (StructField)i.next(); + for (StructField f : fields().values()) { if (f.type.isAssignableFrom(type)) { return f; } @@ -193,6 +203,7 @@ } /** Only the currently selected field will be written. */ + @Override protected void writeField(StructField field) { if (field == activeField) { super.writeField(field); @@ -203,6 +214,7 @@ * selected. Structures may contain pointer-based fields which can * crash the VM if not properly initialized. */ + @Override protected Object readField(StructField field) { if (field == activeField || (!Structure.class.isAssignableFrom(field.type) @@ -213,12 +225,13 @@ // Field not accessible // TODO: read by-value structures, to the extent possible; need a // "read cautiously" method to "read" to indicate we want to avoid - // pointer-based fields + // pointer-based fields return null; } /** All fields are considered the "first" element. */ - protected int getNativeAlignment(Class type, Object value, boolean isFirstElement) { + @Override + protected int getNativeAlignment(Class type, Object value, boolean isFirstElement) { return super.getNativeAlignment(type, value, true); } } diff -Nru libjna-java-4.2.2/src/com/sun/jna/VarArgsChecker.java libjna-java-4.4.0/src/com/sun/jna/VarArgsChecker.java --- libjna-java-4.2.2/src/com/sun/jna/VarArgsChecker.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/VarArgsChecker.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,3 +1,25 @@ +/* + * 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.lang.reflect.Method; @@ -25,6 +47,10 @@ return m.isVarArgs(); } + int fixedArgs(Method m) { + // In Java, final argument contains all "varargs" + return m.isVarArgs() ? m.getParameterTypes().length - 1 : 0; + } } /** @@ -37,6 +63,9 @@ return false; } + int fixedArgs(Method m) { + return 0; + } } /** @@ -68,4 +97,10 @@ */ abstract boolean isVarArgs(Method m); + /** + * If variadic, returns the number of fixed arguments to the method. + * @param m Method to be checked + * @return Number of fixed arguments if the given method takes a variable number of arguments, zero otherwise. + */ + abstract int fixedArgs(Method m); } diff -Nru libjna-java-4.2.2/src/com/sun/jna/Version.java libjna-java-4.4.0/src/com/sun/jna/Version.java --- libjna-java-4.2.2/src/com/sun/jna/Version.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/Version.java 2017-03-14 19:31:03.000000000 +0000 @@ -13,5 +13,5 @@ package com.sun.jna; interface Version { String VERSION = "4.2.0"; - String VERSION_NATIVE = "4.0.1"; + String VERSION_NATIVE = "5.0.1"; } diff -Nru libjna-java-4.2.2/src/com/sun/jna/WeakIdentityHashMap.java libjna-java-4.4.0/src/com/sun/jna/WeakIdentityHashMap.java --- libjna-java-4.2.2/src/com/sun/jna/WeakIdentityHashMap.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/WeakIdentityHashMap.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,181 +0,0 @@ -package com.sun.jna; -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - * Modified to remove Genercs for JNA. - */ - -import java.lang.ref.ReferenceQueue; -import java.lang.ref.WeakReference; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; - - -/** - * Implements a combination of WeakHashMap and IdentityHashMap. - * Useful for caches that need to key off of a == comparison - * instead of a .equals. - * - * - * This class is not a general-purpose Map implementation! While - * this class implements the Map interface, it intentionally violates - * Map's general contract, which mandates the use of the equals method - * when comparing objects. This class is designed for use only in the - * rare cases wherein reference-equality semantics are required. - * - * Note that this implementation is not synchronized. - * - */ -public class WeakIdentityHashMap implements Map { - private final ReferenceQueue queue = new ReferenceQueue(); - private Map backingStore = new HashMap(); - - - public WeakIdentityHashMap() { - } - - - public void clear() { - backingStore.clear(); - reap(); - } - - public boolean containsKey(Object key) { - reap(); - return backingStore.containsKey(new IdentityWeakReference(key)); - } - - public boolean containsValue(Object value) { - reap(); - return backingStore.containsValue(value); - } - - public Set entrySet() { - reap(); - Set ret = new HashSet(); - for (Iterator i=backingStore.entrySet().iterator();i.hasNext();) { - Map.Entry ref = (Map.Entry)i.next(); - final Object key = ((IdentityWeakReference)ref.getKey()).get(); - final Object value = ref.getValue(); - Map.Entry entry = new Map.Entry() { - public Object getKey() { - return key; - } - public Object getValue() { - return value; - } - public Object setValue(Object value) { - throw new UnsupportedOperationException(); - } - }; - ret.add(entry); - } - return Collections.unmodifiableSet(ret); - } - public Set keySet() { - reap(); - Set ret = new HashSet(); - for (Iterator i=backingStore.keySet().iterator();i.hasNext();) { - IdentityWeakReference ref = (IdentityWeakReference)i.next(); - ret.add(ref.get()); - } - return Collections.unmodifiableSet(ret); - } - - public boolean equals(Object o) { - return backingStore.equals(((WeakIdentityHashMap)o).backingStore); - } - - public Object get(Object key) { - reap(); - return backingStore.get(new IdentityWeakReference(key)); - } - public Object put(Object key, Object value) { - reap(); - return backingStore.put(new IdentityWeakReference(key), value); - } - - public int hashCode() { - reap(); - return backingStore.hashCode(); - } - public boolean isEmpty() { - reap(); - return backingStore.isEmpty(); - } - public void putAll(Map t) { - throw new UnsupportedOperationException(); - } - public Object remove(Object key) { - reap(); - return backingStore.remove(new IdentityWeakReference(key)); - } - public int size() { - reap(); - return backingStore.size(); - } - public Collection values() { - reap(); - return backingStore.values(); - } - - private synchronized void reap() { - Object zombie = queue.poll(); - - while (zombie != null) { - IdentityWeakReference victim = (IdentityWeakReference)zombie; - backingStore.remove(victim); - zombie = queue.poll(); - } - } - - class IdentityWeakReference extends WeakReference { - int hash; - - //@SuppressWarnings("unchecked") - IdentityWeakReference(Object obj) { - super(obj, queue); - hash = System.identityHashCode(obj); - } - - public int hashCode() { - return hash; - } - - public boolean equals(Object o) { - if (this == o) { - return true; - } - IdentityWeakReference ref = (IdentityWeakReference)o; - if (this.get() == ref.get()) { - return true; - } - return false; - } - } -} - - - - - \ No newline at end of file diff -Nru libjna-java-4.2.2/src/com/sun/jna/WeakMemoryHolder.java libjna-java-4.4.0/src/com/sun/jna/WeakMemoryHolder.java --- libjna-java-4.2.2/src/com/sun/jna/WeakMemoryHolder.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/WeakMemoryHolder.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,54 @@ +/* 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.lang.ref.Reference; +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.IdentityHashMap; + +/** + * Helper to hold a memory object based on the lifetime of another object. + * + * The intended use is to assoziate a ByteBuffer with its backing Memory object. + * + * The ByteBuffer is held by a WeakReference and a ReferenceQueue is used to + * track GC of the ByteBuffer. + * + * 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>(); + + public synchronized void put(Object o, Memory m) { + clean(); + Reference reference = new WeakReference(o, referenceQueue); + backingMap.put(reference, m); + } + + public synchronized void clean() { + for(Reference ref = referenceQueue.poll(); ref != null; ref = referenceQueue.poll()) { + backingMap.remove(ref); + } + } +} diff -Nru libjna-java-4.2.2/src/com/sun/jna/win32/DLLCallback.java libjna-java-4.4.0/src/com/sun/jna/win32/DLLCallback.java --- libjna-java-4.2.2/src/com/sun/jna/win32/DLLCallback.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/win32/DLLCallback.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2012 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

      - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.win32; diff -Nru libjna-java-4.2.2/src/com/sun/jna/win32/StdCallFunctionMapper.java libjna-java-4.4.0/src/com/sun/jna/win32/StdCallFunctionMapper.java --- libjna-java-4.2.2/src/com/sun/jna/win32/StdCallFunctionMapper.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/win32/StdCallFunctionMapper.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,19 +1,31 @@ /* Copyright (c) 2007 Timothy Wall, 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.win32; import java.lang.reflect.Method; +import com.sun.jna.Function; import com.sun.jna.FunctionMapper; import com.sun.jna.Native; import com.sun.jna.NativeLibrary; @@ -24,7 +36,7 @@ /** Provides mapping from simple method names to w32 stdcall-decorated names * where the name suffix is "@" followed by the number of bytes popped by * the called function.

      - * NOTE: if you use custom type mapping for primitive types, you may need to + * NOTE: if you use custom type mapping for primitive types, you may need to * override {@link #getArgumentNativeStackSize(Class)}. */ public class StdCallFunctionMapper implements FunctionMapper { @@ -32,7 +44,7 @@ * @param cls Java class of a parameter * @return number of native bytes used for this class on the stack */ - protected int getArgumentNativeStackSize(Class cls) { + protected int getArgumentNativeStackSize(Class cls) { if (NativeMapped.class.isAssignableFrom(cls)) { cls = NativeMappedConverter.getInstance(cls).nativeType(); } @@ -41,36 +53,42 @@ } try { return Native.getNativeSize(cls); - } - catch(IllegalArgumentException e) { + } catch(IllegalArgumentException e) { throw new IllegalArgumentException("Unknown native stack allocation size for " + cls); } } - /** Convert the given Java method into a decorated stdcall name, - * if possible. + + /** + * Convert the given Java method into a decorated {@code stdcall} name, if possible. + * + * @param library The {@link NativeLibrary} instance + * @param method The invoked {@link Method} + * @return The decorated name */ + @Override public String getFunctionName(NativeLibrary library, Method method) { String name = method.getName(); int pop = 0; - Class[] argTypes = method.getParameterTypes(); - for (int i=0;i < argTypes.length;i++) { - pop += getArgumentNativeStackSize(argTypes[i]); + Class[] argTypes = method.getParameterTypes(); + for (Class cls : argTypes) { + pop += getArgumentNativeStackSize(cls); } + String decorated = name + "@" + pop; int conv = StdCallLibrary.STDCALL_CONVENTION; try { - name = library.getFunction(decorated, conv).getName(); - - } - catch(UnsatisfiedLinkError e) { + Function func = library.getFunction(decorated, conv); + name = func.getName(); + } catch(UnsatisfiedLinkError e) { // try with an explicit underscore try { - name = library.getFunction("_" + decorated, conv).getName(); - } - catch(UnsatisfiedLinkError e2) { + Function func = library.getFunction("_" + decorated, conv); + name = func.getName(); + } catch(UnsatisfiedLinkError e2) { // not found; let caller try undecorated version } } + return name; } } \ No newline at end of file diff -Nru libjna-java-4.2.2/src/com/sun/jna/win32/StdCall.java libjna-java-4.4.0/src/com/sun/jna/win32/StdCall.java --- libjna-java-4.2.2/src/com/sun/jna/win32/StdCall.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/win32/StdCall.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

      - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.win32; diff -Nru libjna-java-4.2.2/src/com/sun/jna/win32/StdCallLibrary.java libjna-java-4.4.0/src/com/sun/jna/win32/StdCallLibrary.java --- libjna-java-4.2.2/src/com/sun/jna/win32/StdCallLibrary.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/win32/StdCallLibrary.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

      - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.win32; diff -Nru libjna-java-4.2.2/src/com/sun/jna/win32/W32APIFunctionMapper.java libjna-java-4.4.0/src/com/sun/jna/win32/W32APIFunctionMapper.java --- libjna-java-4.2.2/src/com/sun/jna/win32/W32APIFunctionMapper.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/win32/W32APIFunctionMapper.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.win32; diff -Nru libjna-java-4.2.2/src/com/sun/jna/win32/W32APIOptions.java libjna-java-4.4.0/src/com/sun/jna/win32/W32APIOptions.java --- libjna-java-4.2.2/src/com/sun/jna/win32/W32APIOptions.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/win32/W32APIOptions.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,22 +1,51 @@ +/** + * 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.win32; +import java.util.Collections; import java.util.HashMap; import java.util.Map; public interface W32APIOptions extends StdCallLibrary { /** Standard options to use the unicode version of a w32 API. */ - Map UNICODE_OPTIONS = new HashMap() { + Map UNICODE_OPTIONS = Collections.unmodifiableMap(new HashMap() { + private static final long serialVersionUID = 1L; // we're not serializing it + { put(OPTION_TYPE_MAPPER, W32APITypeMapper.UNICODE); put(OPTION_FUNCTION_MAPPER, W32APIFunctionMapper.UNICODE); } - }; + }); + /** Standard options to use the ASCII/MBCS version of a w32 API. */ - Map ASCII_OPTIONS = new HashMap() { + Map ASCII_OPTIONS = Collections.unmodifiableMap(new HashMap() { + private static final long serialVersionUID = 1L; // we're not serializing it { put(OPTION_TYPE_MAPPER, W32APITypeMapper.ASCII); put(OPTION_FUNCTION_MAPPER, W32APIFunctionMapper.ASCII); } - }; - Map DEFAULT_OPTIONS = Boolean.getBoolean("w32.ascii") ? ASCII_OPTIONS : UNICODE_OPTIONS; + }); + + /** Default options to use - depends on the value of {@code w32.ascii} system property */ + Map DEFAULT_OPTIONS = Boolean.getBoolean("w32.ascii") ? ASCII_OPTIONS : UNICODE_OPTIONS; } diff -Nru libjna-java-4.2.2/src/com/sun/jna/win32/W32APITypeMapper.java libjna-java-4.4.0/src/com/sun/jna/win32/W32APITypeMapper.java --- libjna-java-4.2.2/src/com/sun/jna/win32/W32APITypeMapper.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/win32/W32APITypeMapper.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.win32; @@ -20,7 +31,7 @@ import com.sun.jna.TypeMapper; import com.sun.jna.WString; -/** Provide standard conversion for W32 API types. This comprises the +/** Provide standard conversion for W32 API types. This comprises the * following native types: *

        *
      • Unicode or ASCII/MBCS strings and arrays of string, as appropriate @@ -29,13 +40,17 @@ * @author twall */ public class W32APITypeMapper extends DefaultTypeMapper { - + /** Standard TypeMapper to use the unicode version of a w32 API. */ public static final TypeMapper UNICODE = new W32APITypeMapper(true); + /** Standard TypeMapper to use the ASCII/MBCS version of a w32 API. */ public static final TypeMapper ASCII = new W32APITypeMapper(false); - + /** Default TypeMapper to use - depends on the value of {@code w32.ascii} system property */ + public static final TypeMapper DEFAULT = Boolean.getBoolean("w32.ascii") ? ASCII : UNICODE; + protected W32APITypeMapper(boolean unicode) { if (unicode) { TypeConverter stringConverter = new TypeConverter() { + @Override public Object toNative(Object value, ToNativeContext context) { if (value == null) return null; @@ -44,12 +59,14 @@ } return new WString(value.toString()); } + @Override public Object fromNative(Object value, FromNativeContext context) { if (value == null) return null; return value.toString(); } - public Class nativeType() { + @Override + public Class nativeType() { return WString.class; } }; @@ -57,13 +74,16 @@ addToNativeConverter(String[].class, stringConverter); } TypeConverter booleanConverter = new TypeConverter() { + @Override public Object toNative(Object value, ToNativeContext context) { - return new Integer(Boolean.TRUE.equals(value) ? 1 : 0); + return Integer.valueOf(Boolean.TRUE.equals(value) ? 1 : 0); } + @Override public Object fromNative(Object value, FromNativeContext context) { return ((Integer)value).intValue() != 0 ? Boolean.TRUE : Boolean.FALSE; } - public Class nativeType() { + @Override + public Class nativeType() { // BOOL is 32-bit int return Integer.class; } diff -Nru libjna-java-4.2.2/src/com/sun/jna/WString.java libjna-java-4.4.0/src/com/sun/jna/WString.java --- libjna-java-4.2.2/src/com/sun/jna/WString.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/src/com/sun/jna/WString.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,47 +1,65 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

        - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.nio.CharBuffer; - /** Simple wrapper class to identify a wide string argument or return type. - * @author twall@users.sf.net + * @author twall@users.sf.net */ public final class WString implements CharSequence, Comparable { private String string; public WString(String s){ - if (s == null) throw new NullPointerException("String initializer must be non-null"); + if (s == null) { + throw new NullPointerException("String initializer must be non-null"); + } this.string = s; } + @Override public String toString() { return string; } + @Override public boolean equals(Object o) { - return o instanceof WString && toString().equals(o.toString()); + return (o instanceof WString) && toString().equals(o.toString()); } + @Override public int hashCode() { return toString().hashCode(); } + @Override public int compareTo(Object o) { return toString().compareTo(o.toString()); } + @Override public int length() { return toString().length(); } + @Override public char charAt(int index) { return toString().charAt(index); } + @Override public CharSequence subSequence(int start, int end) { - return CharBuffer.wrap(toString()).subSequence(start, end); + return toString().subSequence(start, end); } } diff -Nru libjna-java-4.2.2/test/com/sun/jna/AnnotatedLibraryTest.java libjna-java-4.4.0/test/com/sun/jna/AnnotatedLibraryTest.java --- libjna-java-4.2.2/test/com/sun/jna/AnnotatedLibraryTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/AnnotatedLibraryTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,6 +1,27 @@ +/** + * 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.lang.annotation.Annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -8,9 +29,7 @@ import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; -import java.util.HashMap; -import java.util.Map; - +import java.util.Collections; import junit.framework.TestCase; public class AnnotatedLibraryTest extends TestCase { @@ -22,8 +41,9 @@ public interface AnnotatedLibrary extends Library { @TestAnnotation boolean isAnnotated(); } - + public class TestInvocationHandler implements InvocationHandler { + @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return Boolean.valueOf(method.getAnnotations().length == 1); } @@ -38,7 +58,7 @@ new TestInvocationHandler()); assertTrue("Proxy method not annotated", a.isAnnotated()); } - + @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public static @interface FooBoolean {} @@ -48,32 +68,33 @@ } public void testAnnotationsOnMethods() throws Exception { final int MAGIC = 0xABEDCF23; - Map options = new HashMap(); final boolean[] hasAnnotation = {false, false}; - DefaultTypeMapper mapper = new DefaultTypeMapper(); + DefaultTypeMapper mapper = new DefaultTypeMapper(); mapper.addTypeConverter(Boolean.class, new TypeConverter() { + @Override public Object toNative(Object value, ToNativeContext ctx) { MethodParameterContext mcontext = (MethodParameterContext)ctx; hasAnnotation[0] = mcontext.getMethod().getAnnotation(FooBoolean.class) != null; - return new Integer(Boolean.TRUE.equals(value) ? MAGIC : 0); + return Integer.valueOf(Boolean.TRUE.equals(value) ? MAGIC : 0); } + @Override public Object fromNative(Object value, FromNativeContext context) { - MethodResultContext mcontext = (MethodResultContext)context; + MethodResultContext mcontext = (MethodResultContext)context; hasAnnotation[1] = mcontext.getMethod().getAnnotation(FooBoolean.class) != null; return Boolean.valueOf(((Integer) value).intValue() == MAGIC); } - public Class nativeType() { + @Override + public Class nativeType() { return Integer.class; } }); - - options.put(Library.OPTION_TYPE_MAPPER, mapper); - AnnotationTestLibrary lib = (AnnotationTestLibrary) - Native.loadLibrary("testlib", AnnotationTestLibrary.class, options); + + AnnotationTestLibrary lib = + Native.loadLibrary("testlib", AnnotationTestLibrary.class, Collections.singletonMap(Library.OPTION_TYPE_MAPPER, mapper)); assertEquals("Failed to convert integer return to boolean TRUE", true, lib.returnInt32Argument(true)); - assertTrue("Failed to get annotation from ParameterContext", hasAnnotation[0]); - assertTrue("Failed to get annotation from ResultContext", hasAnnotation[1]); + assertTrue("Failed to get annotation from ParameterContext", hasAnnotation[0]); + assertTrue("Failed to get annotation from ResultContext", hasAnnotation[1]); } public static void main(String[] args) { diff -Nru libjna-java-4.2.2/test/com/sun/jna/ArgumentsMarshalTest.java libjna-java-4.4.0/test/com/sun/jna/ArgumentsMarshalTest.java --- libjna-java-4.2.2/test/com/sun/jna/ArgumentsMarshalTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/ArgumentsMarshalTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

        - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; @@ -29,21 +40,22 @@ private static final String UNICODE = "[\0444]"; public static interface TestLibrary extends Library { - + class CheckFieldAlignment extends Structure { - public static class ByValue extends CheckFieldAlignment + public static class ByValue extends CheckFieldAlignment implements Structure.ByValue { } public static class ByReference extends CheckFieldAlignment implements Structure.ByReference { } - + public byte int8Field; public short int16Field; public int int32Field; public long int64Field; public float floatField; public double doubleField; - - public List getFieldOrder() { + + @Override + public List getFieldOrder() { return Arrays.asList(new String[] { "int8Field", "int16Field", "int32Field", "int64Field", "floatField", "doubleField" }); } public CheckFieldAlignment() { @@ -89,7 +101,7 @@ int testStructureByReferenceArrayInitialization(CheckFieldAlignment.ByReference[] p, int len); void modifyStructureArray(CheckFieldAlignment[] p, int length); void modifyStructureByReferenceArray(CheckFieldAlignment.ByReference[] p, int length); - + int fillInt8Buffer(byte[] buf, int len, byte value); int fillInt16Buffer(short[] buf, int len, short value); int fillInt32Buffer(int[] buf, int len, int value); @@ -97,13 +109,14 @@ int fillFloatBuffer(float[] buf, int len, float value); int fillDoubleBuffer(double[] buf, int len, double value); - // Nonexistent functions + // Nonexistent functions boolean returnBooleanArgument(Object arg); // Structure class MinTestStructure extends Structure { public int field; - protected List getFieldOrder() { + @Override + protected List getFieldOrder() { return Arrays.asList(new String[] { "field" }); } } @@ -112,7 +125,8 @@ class VariableSizedStructure extends Structure { public int length; public byte[] buffer; - protected List getFieldOrder() { + @Override + protected List getFieldOrder() { return Arrays.asList(new String[] { "length", "buffer" }); } public VariableSizedStructure(String arg) { @@ -127,7 +141,8 @@ int callback(int arg1, int arg2); } public TestCallback cb; - protected List getFieldOrder() { + @Override + protected List getFieldOrder() { return Arrays.asList(new String[] { "cb" }); } } @@ -135,14 +150,16 @@ } TestLibrary lib; + @Override protected void setUp() { - lib = (TestLibrary)Native.loadLibrary("testlib", TestLibrary.class); + lib = Native.loadLibrary("testlib", TestLibrary.class); } - + + @Override protected void tearDown() { lib = null; } - + public void testJavaObjectArgument() { Object o = this; try { @@ -159,24 +176,24 @@ } public void testBooleanArgument() { - assertTrue("True argument should be returned", + assertTrue("True argument should be returned", lib.returnBooleanArgument(true)); - assertFalse("False argument should be returned", + assertFalse("False argument should be returned", lib.returnBooleanArgument(false)); } public void testInt8Argument() { byte b = 0; - assertEquals("Wrong value returned", + assertEquals("Wrong value returned", b, lib.returnInt8Argument(b)); b = 127; - assertEquals("Wrong value returned", + assertEquals("Wrong value returned", b, lib.returnInt8Argument(b)); b = -128; - assertEquals("Wrong value returned", + assertEquals("Wrong value returned", b, lib.returnInt8Argument(b)); } - + public void testWideCharArgument() { char c = 0; assertEquals("Wrong value returned", @@ -191,64 +208,64 @@ public void testInt16Argument() { short v = 0; - assertEquals("Wrong value returned", + assertEquals("Wrong value returned", v, lib.returnInt16Argument(v)); v = 32767; - assertEquals("Wrong value returned", + assertEquals("Wrong value returned", v, lib.returnInt16Argument(v)); v = -32768; - assertEquals("Wrong value returned", + assertEquals("Wrong value returned", v, lib.returnInt16Argument(v)); } public void testIntArgument() { int value = 0; - assertEquals("Should return 32-bit argument", + assertEquals("Should return 32-bit argument", value, lib.returnInt32Argument(value)); value = 1; - assertEquals("Should return 32-bit argument", + assertEquals("Should return 32-bit argument", value, lib.returnInt32Argument(value)); value = 0x7FFFFFFF; - assertEquals("Should return 32-bit argument", + assertEquals("Should return 32-bit argument", value, lib.returnInt32Argument(value)); value = 0x80000000; - assertEquals("Should return 32-bit argument", + assertEquals("Should return 32-bit argument", value, lib.returnInt32Argument(value)); } public void testLongArgument() { long value = 0L; - assertEquals("Should return 64-bit argument", + assertEquals("Should return 64-bit argument", value, lib.returnInt64Argument(value)); value = 1L; - assertEquals("Should return 64-bit argument", + assertEquals("Should return 64-bit argument", value, lib.returnInt64Argument(value)); value = 0x7FFFFFFFL; - assertEquals("Should return 64-bit argument", + assertEquals("Should return 64-bit argument", value, lib.returnInt64Argument(value)); value = 0x80000000L; - assertEquals("Should return 64-bit argument", + assertEquals("Should return 64-bit argument", value, lib.returnInt64Argument(value)); value = 0x7FFFFFFF00000000L; - assertEquals("Should return 64-bit argument", + assertEquals("Should return 64-bit argument", value, lib.returnInt64Argument(value)); value = 0x8000000000000000L; - assertEquals("Should return 64-bit argument", + assertEquals("Should return 64-bit argument", value, lib.returnInt64Argument(value)); } public void testNativeLongArgument() { NativeLong value = new NativeLong(0); - assertEquals("Should return 0", + assertEquals("Should return 0", value, lib.returnLongArgument(value)); value = new NativeLong(1); - assertEquals("Should return 1", + assertEquals("Should return 1", value, lib.returnLongArgument(value)); value = new NativeLong(0x7FFFFFFF); - assertEquals("Should return 0x7FFFFFFF", + assertEquals("Should return 0x7FFFFFFF", value, lib.returnLongArgument(value)); value = new NativeLong(0x80000000); - assertEquals("Should return 0x80000000", + assertEquals("Should return 0x80000000", value, lib.returnLongArgument(value)); } @@ -258,6 +275,7 @@ long returnInt64Argument(size_t arg); } public static class size_t extends IntegerType { + private static final long serialVersionUID = 1L; public size_t() { this(0); } @@ -272,19 +290,21 @@ public Custom(int value) { this.value = value; } + @Override public Object fromNative(Object nativeValue, FromNativeContext context) { return new Custom(((Integer)nativeValue).intValue()); } - public Class nativeType() { + @Override + public Class nativeType() { return Integer.class; } + @Override public Object toNative() { - return new Integer(value); + return Integer.valueOf(value); } } protected NativeMappedLibrary loadNativeMappedLibrary() { - return (NativeMappedLibrary) - Native.loadLibrary("testlib", NativeMappedLibrary.class); + return Native.loadLibrary("testlib", NativeMappedLibrary.class); } public void testNativeMappedArgument() { NativeMappedLibrary lib = loadNativeMappedLibrary(); @@ -302,13 +322,13 @@ assertEquals("Argument not mapped", MAGIC64, lib.returnInt64Argument(size)); } } - + public void testPointerArgumentReturn() { assertEquals("Expect null pointer", null, lib.returnPointerArgument(null)); Structure s = new TestLibrary.CheckFieldAlignment(); assertEquals("Expect structure pointer", - s.getPointer(), + s.getPointer(), lib.returnPointerArgument(s.getPointer())); } @@ -323,9 +343,9 @@ assertEquals("Expect null pointer", null, lib.returnWStringArgument(null)); assertEquals("Expect string magic", WMAGIC.toString(), lib.returnWStringArgument(WMAGIC).toString()); } - + public void testInt64ArgumentAlignment() { - long value = lib.checkInt64ArgumentAlignment(0x10101010, 0x1111111111111111L, + long value = lib.checkInt64ArgumentAlignment(0x10101010, 0x1111111111111111L, 0x01010101, 0x2222222222222222L); assertEquals("Improper handling of interspersed int32/int64", 0x3333333344444444L, value); @@ -340,7 +360,7 @@ public void testStructurePointerArgument() { TestLibrary.CheckFieldAlignment struct = new TestLibrary.CheckFieldAlignment(); assertEquals("Native address of structure should be returned", - struct.getPointer(), + struct.getPointer(), lib.testStructurePointerArgument(struct)); // ensure that even if the argument is ByValue, it's passed as ptr struct = new TestLibrary.CheckFieldAlignment.ByValue(); @@ -355,12 +375,12 @@ } public void testStructureByValueArgument() { - TestLibrary.CheckFieldAlignment.ByValue struct = + TestLibrary.CheckFieldAlignment.ByValue struct = new TestLibrary.CheckFieldAlignment.ByValue(); assertEquals("Wrong alignment in " + struct.toString(true), "0", Integer.toHexString(lib.testStructureByValueArgument(struct))); } - + public void testStructureByValueTypeInfo() { class TestStructure extends Structure implements Structure.ByValue { public byte b; @@ -372,7 +392,8 @@ public double d; public Pointer[] parray = new Pointer[2]; public byte[] barray = new byte[2]; - protected List getFieldOrder() { + @Override + protected List getFieldOrder() { return Arrays.asList(new String[] { "b", "c", "s", "i", "j", "f", "d", "parray", "barray" }); } } @@ -381,23 +402,23 @@ s.size(); } - + public void testWriteStructureArrayArgumentMemory() { final int LENGTH = 10; TestLibrary.CheckFieldAlignment block = new TestLibrary.CheckFieldAlignment(); - TestLibrary.CheckFieldAlignment[] array = + TestLibrary.CheckFieldAlignment[] array = (TestLibrary.CheckFieldAlignment[])block.toArray(LENGTH); for (int i=0;i < array.length;i++) { array[i].int32Field = i; } assertEquals("Structure array memory not properly initialized", -1, lib.testStructureArrayInitialization(array, array.length)); - + } - + public void testUninitializedStructureArrayArgument() { final int LENGTH = 10; - TestLibrary.CheckFieldAlignment[] block = + TestLibrary.CheckFieldAlignment[] block = new TestLibrary.CheckFieldAlignment[LENGTH]; lib.modifyStructureArray(block, block.length); for (int i=0;i < block.length;i++) { @@ -426,7 +447,7 @@ catch(IllegalArgumentException e) { } } - + public void testRejectIncompatibleStructureArrayArgument() { TestLibrary.CheckFieldAlignment s1 = new TestLibrary.CheckFieldAlignment.ByReference(); TestLibrary.CheckFieldAlignment[] autoArray = (TestLibrary.CheckFieldAlignment[])s1.toArray(3); @@ -489,43 +510,43 @@ public void testByteArrayArgument() { byte[] buf = new byte[1024]; final byte MAGIC = (byte)0xED; - assertEquals("Wrong return value", buf.length, + assertEquals("Wrong return value", buf.length, lib.fillInt8Buffer(buf, buf.length, MAGIC)); for (int i=0;i < buf.length;i++) { assertEquals("Bad value at index " + i, MAGIC, buf[i]); } } - + public void testShortArrayArgument() { short[] buf = new short[1024]; final short MAGIC = (short)0xABED; - assertEquals("Wrong return value", buf.length, + assertEquals("Wrong return value", buf.length, lib.fillInt16Buffer(buf, buf.length, MAGIC)); for (int i=0;i < buf.length;i++) { assertEquals("Bad value at index " + i, MAGIC, buf[i]); } } - + public void testIntArrayArgument() { int[] buf = new int[1024]; final int MAGIC = 0xABEDCF23; - assertEquals("Wrong return value", buf.length, + assertEquals("Wrong return value", buf.length, lib.fillInt32Buffer(buf, buf.length, MAGIC)); for (int i=0;i < buf.length;i++) { assertEquals("Bad value at index " + i, MAGIC, buf[i]); } } - - public void testLongArrayArgument() { + + public void testLongArrayArgument() { long[] buf = new long[1024]; final long MAGIC = 0x1234567887654321L; - assertEquals("Wrong return value", buf.length, + assertEquals("Wrong return value", buf.length, lib.fillInt64Buffer(buf, buf.length, MAGIC)); for (int i=0;i < buf.length;i++) { assertEquals("Bad value at index " + i, MAGIC, buf[i]); } } - + public void testUnsupportedJavaObjectArgument() { try { lib.returnBooleanArgument(this); @@ -534,23 +555,23 @@ catch(IllegalArgumentException e) { } } - + public void testStringArrayArgument() { String[] args = { "one"+UNICODE, "two"+UNICODE, "three"+UNICODE }; assertEquals("Wrong value returned", args[0], lib.returnStringArrayElement(args, 0)); - assertNull("Native String array should be null terminated", + assertNull("Native String array should be null terminated", lib.returnStringArrayElement(args, args.length)); } - + public void testWideStringArrayArgument() { WString[] args = { new WString("one"+UNICODE), new WString("two"+UNICODE), new WString("three"+UNICODE) }; assertEquals("Wrong value returned", args[0], lib.returnWideStringArrayElement(args, 0)); assertNull("Native WString array should be null terminated", lib.returnWideStringArrayElement(args, args.length)); } - + public void testPointerArrayArgument() { - Pointer[] args = { + Pointer[] args = { new NativeString(getName()).getPointer(), null, new NativeString(getName()+"2").getPointer(), @@ -581,7 +602,7 @@ }; public void testStructureByReferenceArrayArgument() { - CheckFieldAlignment.ByReference[] args = { + CheckFieldAlignment.ByReference[] args = { new CheckFieldAlignment.ByReference(), null, new CheckFieldAlignment.ByReference(), @@ -599,7 +620,7 @@ Arrays.asList(new String[] { "two", "three", "one" }), Arrays.asList(args)); } - + public void testReadFunctionPointerAsCallback() { TestLibrary.CbStruct s = new TestLibrary.CbStruct(); assertNull("Function pointer field should be null", s.cb); @@ -640,5 +661,5 @@ public static void main(java.lang.String[] argList) { junit.textui.TestRunner.run(ArgumentsMarshalTest.class); } - + } diff -Nru libjna-java-4.2.2/test/com/sun/jna/BufferArgumentsMarshalTest.java libjna-java-4.4.0/test/com/sun/jna/BufferArgumentsMarshalTest.java --- libjna-java-4.2.2/test/com/sun/jna/BufferArgumentsMarshalTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/BufferArgumentsMarshalTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

        - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; @@ -19,10 +30,6 @@ import java.nio.IntBuffer; import java.nio.LongBuffer; import java.nio.ShortBuffer; -import java.util.Arrays; - -import com.sun.jna.ArgumentsMarshalTest.TestLibrary.CheckFieldAlignment; - import junit.framework.TestCase; /** Exercise a range of native methods. @@ -33,7 +40,7 @@ public class BufferArgumentsMarshalTest extends TestCase { public static interface TestLibrary extends Library { - + // ByteBuffer alternative definitions int fillInt8Buffer(ByteBuffer buf, int len, byte value); int fillInt16Buffer(ByteBuffer buf, int len, short value); @@ -41,7 +48,7 @@ int fillInt64Buffer(ByteBuffer buf, int len, long value); int fillFloatBuffer(ByteBuffer buf, int len, float value); int fillDoubleBuffer(ByteBuffer buf, int len, double value); - + // {Short|Int|Long|,Float|Double}Buffer alternative definitions int fillInt16Buffer(ShortBuffer buf, int len, short value); int fillInt32Buffer(IntBuffer buf, int len, int value); @@ -51,14 +58,16 @@ } TestLibrary lib; + @Override protected void setUp() { - lib = (TestLibrary)Native.loadLibrary("testlib", TestLibrary.class); + lib = Native.loadLibrary("testlib", TestLibrary.class); } - + + @Override protected void tearDown() { lib = null; } - + public void testByteBufferArgument() { ByteBuffer buf = ByteBuffer.allocate(1024).order(ByteOrder.nativeOrder()); final byte MAGIC = (byte)0xED; @@ -91,7 +100,7 @@ assertEquals("Bad value at index " + i, MAGIC, buf.get(i)); } } - + public void testDirectByteBufferArgument() { ByteBuffer buf = ByteBuffer.allocateDirect(1024).order(ByteOrder.nativeOrder()); final byte MAGIC = (byte)0xED; @@ -106,7 +115,7 @@ i < 512 ? MAGIC : 0, buf.get(i)); } } - + public void testDirectShortBufferArgument() { ByteBuffer buf = ByteBuffer.allocateDirect(1024*2).order(ByteOrder.nativeOrder()); ShortBuffer shortBuf = buf.asShortBuffer(); @@ -116,7 +125,7 @@ assertEquals("Bad value at index " + i, MAGIC, shortBuf.get(i)); } } - + public void testDirectIntBufferArgument() { ByteBuffer buf = ByteBuffer.allocateDirect(1024*4).order(ByteOrder.nativeOrder()); IntBuffer intBuf = buf.asIntBuffer(); @@ -126,7 +135,7 @@ assertEquals("Bad value at index " + i, MAGIC, intBuf.get(i)); } } - + public void testDirectLongBufferArgument() { ByteBuffer buf = ByteBuffer.allocateDirect(1024*8).order(ByteOrder.nativeOrder()); LongBuffer longBuf = buf.asLongBuffer(); @@ -136,7 +145,7 @@ assertEquals("Bad value at index " + i, MAGIC, longBuf.get(i)); } } - + public void testWrappedByteArrayArgument() { byte[] array = new byte[1024]; ByteBuffer buf = ByteBuffer.wrap(array, 512, 512); @@ -197,9 +206,9 @@ i < 512 ? 0 : MAGIC, array[i]); } } - + public static void main(java.lang.String[] argList) { junit.textui.TestRunner.run(BufferArgumentsMarshalTest.class); } - + } diff -Nru libjna-java-4.2.2/test/com/sun/jna/ByReferenceArgumentsTest.java libjna-java-4.4.0/test/com/sun/jna/ByReferenceArgumentsTest.java --- libjna-java-4.2.2/test/com/sun/jna/ByReferenceArgumentsTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/ByReferenceArgumentsTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

        - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; @@ -41,10 +52,12 @@ } TestLibrary lib; + @Override protected void setUp() { - lib = (TestLibrary)Native.loadLibrary("testlib", TestLibrary.class); + lib = Native.loadLibrary("testlib", TestLibrary.class); } - + + @Override protected void tearDown() { lib = null; } @@ -93,9 +106,9 @@ lib.setPointerByReferenceNull(pref); assertNull("Default pointer should be NULL after call", pref.getValue()); } - + public static void main(java.lang.String[] argList) { junit.textui.TestRunner.run(ByReferenceArgumentsTest.class); } - + } diff -Nru libjna-java-4.2.2/test/com/sun/jna/CallbacksTest.java libjna-java-4.4.0/test/com/sun/jna/CallbacksTest.java --- libjna-java-4.2.2/test/com/sun/jna/CallbacksTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/CallbacksTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,37 +1,49 @@ /* Copyright (c) 2007-2013 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

        - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.io.ByteArrayOutputStream; -import java.io.File; import java.io.PrintStream; +import java.lang.ref.Reference; import java.lang.ref.WeakReference; +import java.nio.charset.Charset; import java.util.Arrays; -import java.util.HashMap; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.WeakHashMap; -import junit.framework.TestCase; - import com.sun.jna.Callback.UncaughtExceptionHandler; import com.sun.jna.CallbacksTest.TestLibrary.CbCallback; import com.sun.jna.ptr.IntByReference; import com.sun.jna.ptr.PointerByReference; import com.sun.jna.win32.W32APIOptions; +import junit.framework.TestCase; + /** Exercise callback-related functionality. * * @author twall@users.sf.net @@ -39,7 +51,7 @@ //@SuppressWarnings("unused") public class CallbacksTest extends TestCase implements Paths { - // On OSX, on Oracle JVM 1.8+, pthread cleanup thinks the native thread is + // On OSX, on Oracle JVM 1.8+, pthread cleanup thinks the native thread is // not attached, and the JVM never unmaps the defunct native thread. In // order to avoid this situation causing tests to time out, we need to // explicitly detach the native thread after our Java code is done with it. @@ -65,16 +77,19 @@ } public static class SmallTestStructure extends Structure { + public static final List FIELDS = createFieldsOrder("value"); public double value; public static int allocations = 0; + @Override protected void allocateMemory(int size) { super.allocateMemory(size); ++allocations; } public SmallTestStructure() { } public SmallTestStructure(Pointer p) { super(p); read(); } - protected List getFieldOrder() { - return Arrays.asList(new String[] { "value" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } public static class TestStructure extends Structure { @@ -82,13 +97,16 @@ public static interface TestCallback extends Callback { TestStructure.ByValue callback(TestStructure.ByValue s); } + + public static final List FIELDS = createFieldsOrder("c", "s", "i", "j", "inner"); public byte c; public short s; public int i; public long j; public SmallTestStructure inner; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "c", "s", "i", "j", "inner" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } public static interface TestLibrary extends Library { @@ -114,6 +132,7 @@ void customMethodName(); } abstract class VoidCallbackCustomAbstract implements VoidCallbackCustom { + @Override public void customMethodName() { } } class VoidCallbackCustomDerived extends VoidCallbackCustomAbstract { } @@ -189,7 +208,8 @@ class CbStruct extends Structure { public Callback cb; - protected List getFieldOrder() { + @Override + protected List getFieldOrder() { return Arrays.asList(new String[] { "cb" }); } } @@ -208,10 +228,12 @@ TestLibrary lib; + @Override protected void setUp() { - lib = (TestLibrary)Native.loadLibrary("testlib", TestLibrary.class); + lib = Native.loadLibrary("testlib", TestLibrary.class); } - + + @Override protected void tearDown() { lib = null; } @@ -222,15 +244,19 @@ public Custom(int value) { this.value = value; } + @Override public Object fromNative(Object nativeValue, FromNativeContext context) { return new Custom(((Integer)nativeValue).intValue()); } - public Class nativeType() { + @Override + public Class nativeType() { return Integer.class; } + @Override public Object toNative() { - return new Integer(value); + return Integer.valueOf(value); } + @Override public boolean equals(Object o) { return o instanceof Custom && ((Custom)o).value == value; } @@ -242,8 +268,8 @@ try { CallbackReference.getCallback(TestLibrary.VoidCallback.class, new Pointer(0)); fail("Null pointer lookup should fail"); - } - catch(NullPointerException e) { + } catch(NullPointerException e) { + // expected } } @@ -295,7 +321,7 @@ public void testNativeFunctionPointerStringValue() { Callback cb = CallbackReference.getCallback(TestLibrary.VoidCallback.class, new Pointer(getName().hashCode())); - Class cls = CallbackReference.findCallbackClass(cb.getClass()); + Class cls = CallbackReference.findCallbackClass(cb.getClass()); assertTrue("toString should include Java Callback type: " + cb + " (" + cls + ")", cb.toString().indexOf(cls.getName()) != -1); } @@ -303,12 +329,12 @@ public void testLookupSameCallback() { Callback cb = CallbackReference.getCallback(TestLibrary.VoidCallback.class, new Pointer(getName().hashCode())); Callback cb2 = CallbackReference.getCallback(TestLibrary.VoidCallback.class, new Pointer(getName().hashCode())); - + assertEquals("Callback lookups for same pointer should return same Callback object", cb, cb2); } // Allow direct tests to override - protected Map callbackCache() { + protected Map callbackCache() { return CallbackReference.callbackMap; } @@ -316,30 +342,29 @@ public void testGCCallbackOnFinalize() throws Exception { final boolean[] called = { false }; TestLibrary.VoidCallback cb = new TestLibrary.VoidCallback() { + @Override public void callback() { called[0] = true; } }; 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 = (CallbackReference)refs.get(cb); + CallbackReference ref = refs.get(cb); refs = callbackCache(); Pointer cbstruct = ref.cbstruct; - + cb = null; System.gc(); for (int i = 0; i < 100 && (ref.get() != null || refs.containsValue(ref)); ++i) { - try { - Thread.sleep(10); // Give the GC a chance to run - System.gc(); - } finally {} + Thread.sleep(10); // Give the GC a chance to run + System.gc(); } assertNull("Callback not GC'd", ref.get()); assertFalse("Callback still in map", refs.containsValue(ref)); - + ref = null; System.gc(); for (int i = 0; i < 100 && (cbstruct.peer != 0 || refs.size() > 0); ++i) { @@ -352,9 +377,10 @@ } assertEquals("Callback trampoline not freed", 0, cbstruct.peer); } - + public void testFindCallbackInterface() { TestLibrary.Int32Callback cb = new TestLibrary.Int32Callback() { + @Override public int callback(int arg, int arg2) { return arg + arg2; } @@ -367,6 +393,7 @@ public void testCallVoidCallback() { final boolean[] called = { false }; TestLibrary.VoidCallback cb = new TestLibrary.VoidCallback() { + @Override public void callback() { called[0] = true; } @@ -379,6 +406,7 @@ final int MAGIC = 0x11111111; final boolean[] called = { false }; TestLibrary.Int32Callback cb = new TestLibrary.Int32Callback() { + @Override public int callback(int arg, int arg2) { called[0] = true; return arg + arg2; @@ -387,17 +415,18 @@ final int EXPECTED = MAGIC*3; int value = lib.callInt32Callback(cb, MAGIC, MAGIC*2); assertTrue("Callback not called", called[0]); - assertEquals("Wrong callback value", Integer.toHexString(EXPECTED), + assertEquals("Wrong callback value", Integer.toHexString(EXPECTED), Integer.toHexString(value)); - + value = lib.callInt32Callback(cb, -1, -2); assertEquals("Wrong callback return", -3, value); } - + public void testCallInt64Callback() { final long MAGIC = 0x1111111111111111L; final boolean[] called = { false }; TestLibrary.Int64Callback cb = new TestLibrary.Int64Callback() { + @Override public long callback(long arg, long arg2) { called[0] = true; return arg + arg2; @@ -406,17 +435,18 @@ final long EXPECTED = MAGIC*3; long value = lib.callInt64Callback(cb, MAGIC, MAGIC*2); assertTrue("Callback not called", called[0]); - assertEquals("Wrong callback value", Long.toHexString(EXPECTED), + assertEquals("Wrong callback value", Long.toHexString(EXPECTED), Long.toHexString(value)); - + value = lib.callInt64Callback(cb, -1, -2); assertEquals("Wrong callback return", -3, value); } - + public void testCallFloatCallback() { final boolean[] called = { false }; final float[] args = { 0, 0 }; TestLibrary.FloatCallback cb = new TestLibrary.FloatCallback() { + @Override public float callback(float arg, float arg2) { called[0] = true; args[0] = arg; @@ -430,15 +460,16 @@ assertEquals("Wrong first argument", FLOAT_MAGIC, args[0], 0); assertEquals("Wrong second argument", FLOAT_MAGIC*2, args[1], 0); assertEquals("Wrong callback value", EXPECTED, value, 0); - + value = lib.callFloatCallback(cb, -1f, -2f); assertEquals("Wrong callback return", -3f, value, 0); } - + public void testCallDoubleCallback() { final boolean[] called = { false }; final double[] args = { 0, 0 }; TestLibrary.DoubleCallback cb = new TestLibrary.DoubleCallback() { + @Override public double callback(double arg, double arg2) { called[0] = true; args[0] = arg; @@ -451,18 +482,19 @@ assertTrue("Callback not called", called[0]); assertEquals("Wrong first argument", DOUBLE_MAGIC, args[0], 0); assertEquals("Wrong second argument", DOUBLE_MAGIC*2, args[1], 0); - assertEquals("Wrong callback value", EXPECTED, value, 0); - + assertEquals("Wrong callback value", EXPECTED, value, 0); + value = lib.callDoubleCallback(cb, -1d, -2d); assertEquals("Wrong callback return", -3d, value, 0); } - + public void testCallStructureCallback() { final boolean[] called = {false}; final Pointer[] cbarg = { null }; final SmallTestStructure s = new SmallTestStructure(); final double MAGIC = 118.625; TestLibrary.StructureCallback cb = new TestLibrary.StructureCallback() { + @Override public SmallTestStructure callback(SmallTestStructure arg) { called[0] = true; cbarg[0] = arg.getPointer(); @@ -480,15 +512,16 @@ assertEquals("Structure return not synched", MAGIC, value.value, 0d); // All structures involved should be created from pointers, with no - // memory allocation at all. + // memory allocation at all. assertEquals("No structure memory should be allocated", 0, SmallTestStructure.allocations); } - + public void testCallStructureArrayCallback() { final SmallTestStructure s = new SmallTestStructure(); final SmallTestStructure[] array = (SmallTestStructure[])s.toArray(2); final double MAGIC = 118.625; TestLibrary.StructureCallback cb = new TestLibrary.StructureCallback() { + @Override public SmallTestStructure callback(SmallTestStructure arg) { SmallTestStructure[] array = (SmallTestStructure[])arg.toArray(2); @@ -503,11 +536,12 @@ assertEquals("Structure array element 1 not synched on callback return", MAGIC*2, array[1].value, 0d); } - + public void testCallBooleanCallback() { final boolean[] called = {false}; final boolean[] cbargs = { false, false }; TestLibrary.BooleanCallback cb = new TestLibrary.BooleanCallback() { + @Override public boolean callback(boolean arg, boolean arg2) { called[0] = true; cbargs[0] = arg; @@ -521,11 +555,12 @@ assertEquals("Wrong second callback argument", false, cbargs[1]); assertFalse("Wrong boolean return", value); } - + public void testCallInt8Callback() { final boolean[] called = {false}; final byte[] cbargs = { 0, 0 }; TestLibrary.ByteCallback cb = new TestLibrary.ByteCallback() { + @Override public byte callback(byte arg, byte arg2) { called[0] = true; cbargs[0] = arg; @@ -533,27 +568,28 @@ return (byte)(arg + arg2); } }; - final byte MAGIC = 0x11; + final byte MAGIC = 0x11; byte value = lib.callInt8Callback(cb, MAGIC, (byte)(MAGIC*2)); assertTrue("Callback not called", called[0]); - assertEquals("Wrong first callback argument", - Integer.toHexString(MAGIC), + assertEquals("Wrong first callback argument", + Integer.toHexString(MAGIC), Integer.toHexString(cbargs[0])); - assertEquals("Wrong second callback argument", - Integer.toHexString(MAGIC*2), + assertEquals("Wrong second callback argument", + Integer.toHexString(MAGIC*2), Integer.toHexString(cbargs[1])); - assertEquals("Wrong byte return", - Integer.toHexString(MAGIC*3), + assertEquals("Wrong byte return", + Integer.toHexString(MAGIC*3), Integer.toHexString(value)); - + value = lib.callInt8Callback(cb, (byte)-1, (byte)-2); assertEquals("Wrong byte return (hi bit)", (byte)-3, value); } - + public void testCallInt16Callback() { final boolean[] called = {false}; final short[] cbargs = { 0, 0 }; TestLibrary.ShortCallback cb = new TestLibrary.ShortCallback() { + @Override public short callback(short arg, short arg2) { called[0] = true; cbargs[0] = arg; @@ -564,24 +600,25 @@ final short MAGIC = 0x1111; short value = lib.callInt16Callback(cb, MAGIC, (short)(MAGIC*2)); assertTrue("Callback not called", called[0]); - assertEquals("Wrong first callback argument", - Integer.toHexString(MAGIC), + assertEquals("Wrong first callback argument", + Integer.toHexString(MAGIC), Integer.toHexString(cbargs[0])); - assertEquals("Wrong second callback argument", - Integer.toHexString(MAGIC*2), + assertEquals("Wrong second callback argument", + Integer.toHexString(MAGIC*2), Integer.toHexString(cbargs[1])); - assertEquals("Wrong short return", - Integer.toHexString(MAGIC*3), + assertEquals("Wrong short return", + Integer.toHexString(MAGIC*3), Integer.toHexString(value)); value = lib.callInt16Callback(cb, (short)-1, (short)-2); assertEquals("Wrong short return (hi bit)", (short)-3, value); } - + public void testCallNativeLongCallback() { final boolean[] called = {false}; final NativeLong[] cbargs = { null, null}; TestLibrary.NativeLongCallback cb = new TestLibrary.NativeLongCallback() { + @Override public NativeLong callback(NativeLong arg, NativeLong arg2) { called[0] = true; cbargs[0] = arg; @@ -595,11 +632,12 @@ assertEquals("Wrong second callback argument", new NativeLong(2), cbargs[1]); assertEquals("Wrong boolean return", new NativeLong(3), value); } - + public void testCallNativeMappedCallback() { final boolean[] called = {false}; final Custom[] cbargs = { null, null}; TestLibrary.CustomCallback cb = new TestLibrary.CustomCallback() { + @Override public Custom callback(Custom arg, Custom arg2) { called[0] = true; cbargs[0] = arg; @@ -613,11 +651,12 @@ assertEquals("Wrong second callback argument", new Custom(2), cbargs[1]); assertEquals("Wrong NativeMapped return", 3, value); } - + public void testCallStringCallback() { final boolean[] called = {false}; final String[] cbargs = { null, null }; TestLibrary.StringCallback cb = new TestLibrary.StringCallback() { + @Override public String callback(String arg, String arg2) { called[0] = true; cbargs[0] = arg; @@ -625,31 +664,34 @@ return arg + arg2; } }; - final String VALUE = "value" + UNICODE; - final String VALUE2 = getName() + UNICODE; + Charset charset = Charset.forName(Native.getDefaultStringEncoding()); + final String VALUE = "value" + charset.decode(charset.encode(UNICODE)); + final String VALUE2 = getName() + charset.decode(charset.encode(UNICODE)); String value = lib.callStringCallback(cb, VALUE, VALUE2); assertTrue("Callback not called", called[0]); assertEquals("Wrong String callback argument 0", VALUE, cbargs[0]); assertEquals("Wrong String callback argument 1", VALUE2, cbargs[1]); assertEquals("Wrong String return", VALUE + VALUE2, value); } - + public void testStringCallbackMemoryReclamation() throws InterruptedException { TestLibrary.StringCallback cb = new TestLibrary.StringCallback() { + @Override public String callback(String arg, String arg2) { return arg + arg2; } }; // A little internal groping - Map m = CallbackReference.allocations; + Map m = CallbackReference.allocations; m.clear(); - String arg = getName() + "1" + UNICODE; - String arg2 = getName() + "2" + UNICODE; + Charset charset = Charset.forName(Native.getDefaultStringEncoding()); + 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; System.gc(); @@ -667,6 +709,7 @@ final boolean[] called = {false}; final WString[] cbargs = { null, null }; TestLibrary.WideStringCallback cb = new TestLibrary.WideStringCallback() { + @Override public WString callback(WString arg, WString arg2) { called[0] = true; cbargs[0] = arg; @@ -682,18 +725,20 @@ assertEquals("Wrong second callback argument", VALUE2, cbargs[1]); assertEquals("Wrong wide string return", new WString(VALUE.toString() + VALUE2.toString()), value); } - + public void testCallStringArrayCallback() { final boolean[] called = {false}; final String[][] cbargs = { null }; TestLibrary.StringArrayCallback cb = new TestLibrary.StringArrayCallback() { + @Override public String[] callback(String[] arg) { called[0] = true; cbargs[0] = arg; return arg; } }; - final String VALUE = "value" + UNICODE; + Charset charset = Charset.forName(Native.getDefaultStringEncoding()); + final String VALUE = "value" + charset.decode(charset.encode(UNICODE)); final String[] VALUE_ARRAY = { VALUE, null }; Pointer value = lib.callStringArrayCallback(cb, VALUE_ARRAY); assertTrue("Callback not called", called[0]); @@ -708,10 +753,11 @@ assertEquals("Terminating null should be removed from return value", VALUE_ARRAY.length-1, result.length); } - + public void testCallCallbackWithByReferenceArgument() { final boolean[] called = {false}; TestLibrary.CopyArgToByReference cb = new TestLibrary.CopyArgToByReference() { + @Override public int callback(int arg, IntByReference result) { called[0] = true; result.setValue(arg); @@ -724,12 +770,13 @@ assertEquals("Wrong value returned", VALUE, value); assertEquals("Wrong value in by reference memory", VALUE, ref.getValue()); } - + public void testCallCallbackWithStructByValue() throws Exception { final boolean[] called = { false }; final TestStructure.ByValue[] arg = { null }; final TestStructure.ByValue s = new TestStructure.ByValue(); TestStructure.TestCallback cb = new TestStructure.TestCallback() { + @Override public TestStructure.ByValue callback(TestStructure.ByValue s) { // Copy the argument value for later comparison called[0] = true; @@ -741,7 +788,7 @@ s.i = 0x33333333; s.j = 0x4444444444444444L; s.inner.value = 5; - + TestStructure result = lib.callCallbackWithStructByValue(cb, s); assertTrue("Callback not called", called[0]); assertTrue("ByValue argument should own its own memory, instead was " @@ -759,15 +806,17 @@ } assertTrue("Wrong value for callback result", s.dataEquals(result, true)); } - - public void testUnionByValueCallbackArgument() throws Exception{ + + public void testUnionByValueCallbackArgument() throws Exception{ TestLibrary.TestUnion arg = new TestLibrary.TestUnion(); arg.setType(String.class); - final String VALUE = getName() + UNICODE; + Charset charset = Charset.forName(arg.getStringEncoding()); + final String VALUE = getName() + charset.decode(charset.encode(UNICODE)); arg.f1 = VALUE; final boolean[] called = { false }; final TestLibrary.TestUnion[] cbvalue = { null }; TestLibrary.TestUnion result = lib.testUnionByValueCallbackArgument(new TestLibrary.UnionCallback() { + @Override public TestLibrary.TestUnion invoke(TestLibrary.TestUnion v) { called[0] = true; v.setType(String.class); @@ -786,6 +835,7 @@ public void testCallCallbackWithCallbackArgumentAndResult() { TestLibrary.CbCallback cb = new TestLibrary.CbCallback() { + @Override public CbCallback callback(CbCallback arg) { return arg; } @@ -793,7 +843,7 @@ TestLibrary.CbCallback cb2 = lib.callCallbackWithCallback(cb); assertEquals("Callback reference should be reused", cb, cb2); } - + public void testDefaultCallbackExceptionHandler() { final RuntimeException ERROR = new RuntimeException(getName()); PrintStream ps = System.err; @@ -801,6 +851,7 @@ System.setErr(new PrintStream(s)); try { TestLibrary.CbCallback cb = new TestLibrary.CbCallback() { + @Override public CbCallback callback(CbCallback arg) { throw ERROR; } @@ -822,6 +873,7 @@ final Callback CALLBACK[] = { null }; UncaughtExceptionHandler old = Native.getCallbackExceptionHandler(); UncaughtExceptionHandler handler = new UncaughtExceptionHandler() { + @Override public void uncaughtException(Callback cb, Throwable e) { CALLBACK[0] = cb; CAUGHT[0] = e; @@ -830,6 +882,7 @@ Native.setCallbackExceptionHandler(handler); try { TestLibrary.CbCallback cb = new TestLibrary.CbCallback() { + @Override public CbCallback callback(CbCallback arg) { throw ERROR; } @@ -852,6 +905,7 @@ final Callback CALLBACK[] = { null }; UncaughtExceptionHandler old = Native.getCallbackExceptionHandler(); UncaughtExceptionHandler handler = new UncaughtExceptionHandler() { + @Override public void uncaughtException(Callback cb, Throwable e) { CALLBACK[0] = cb; CAUGHT[0] = e; @@ -860,16 +914,20 @@ Native.setCallbackExceptionHandler(handler); try { class TestProxy implements CallbackProxy, TestLibrary.CbCallback { + @Override public CbCallback callback(CbCallback arg) { throw new Error("Should never be called"); } + @Override public Object callback(Object[] args) { throw ERROR; } - public Class[] getParameterTypes() { + @Override + public Class[] getParameterTypes() { return new Class[] { CbCallback.class }; } - public Class getReturnType() { + @Override + public Class getReturnType() { return CbCallback.class; } }; @@ -895,8 +953,9 @@ TestLibrary.Int32CallbackX cb = lib.returnCallback(); assertNotNull("Callback should not be null", cb); assertEquals("Callback should be callable", 1, cb.callback(1)); - + TestLibrary.Int32CallbackX cb2 = new TestLibrary.Int32CallbackX() { + @Override public int callback(int arg) { return 0; } @@ -906,7 +965,7 @@ assertSame("Existing native function wrapper should be reused", cb, lib.returnCallbackArgument(cb)); } - + public void testCallCallbackInStructure() { final boolean[] flag = {false}; final TestLibrary.CbStruct s = new TestLibrary.CbStruct(); @@ -922,9 +981,11 @@ public void testCustomCallbackMethodName() { final boolean[] called = {false}; TestLibrary.VoidCallbackCustom cb = new TestLibrary.VoidCallbackCustom() { + @Override public void customMethodName() { called[0] = true; } + @Override public String toString() { return "Some debug output"; } @@ -937,6 +998,7 @@ final boolean[] called = {false}; final boolean[] exceptionThrown = {true}; TestLibrary.VoidCallback cb = new TestLibrary.VoidCallback() { + @Override public void callback() { called[0] = true; try { @@ -961,41 +1023,48 @@ protected static class CallbackTypeMapper extends DefaultTypeMapper { public int fromNativeConversions = 0; public int toNativeConversions = 0; - public void clear() { + public void clear() { fromNativeConversions = 0; toNativeConversions = 0; } { // Convert java doubles into native integers and back TypeConverter converter = new TypeConverter() { + @Override public Object fromNative(Object value, FromNativeContext context) { ++fromNativeConversions; - return new Double(((Integer)value).intValue()); + return Double.valueOf(((Integer)value).intValue()); } - public Class nativeType() { + @Override + public Class nativeType() { return Integer.class; } + @Override public Object toNative(Object value, ToNativeContext ctx) { ++toNativeConversions; - return new Integer(((Double)value).intValue()); + return Integer.valueOf(((Double)value).intValue()); } }; addTypeConverter(double.class, converter); converter = new TypeConverter() { + @Override public Object fromNative(Object value, FromNativeContext context) { ++fromNativeConversions; - return new Float(((Long)value).intValue()); + return Float.valueOf(((Long)value).intValue()); } - public Class nativeType() { + @Override + public Class nativeType() { return Long.class; } + @Override public Object toNative(Object value, ToNativeContext ctx) { ++toNativeConversions; - return new Long(((Float)value).longValue()); + return Long.valueOf(((Float)value).longValue()); } }; addTypeConverter(float.class, converter); converter = new TypeConverter() { + @Override public Object fromNative(Object value, FromNativeContext context) { ++fromNativeConversions; if (value == null) { @@ -1006,9 +1075,11 @@ } return value.toString(); } - public Class nativeType() { + @Override + public Class nativeType() { return WString.class; } + @Override public Object toNative(Object value, ToNativeContext ctx) { ++toNativeConversions; return new WString(value.toString()); @@ -1020,11 +1091,8 @@ public static interface CallbackTestLibrary extends Library { final CallbackTypeMapper _MAPPER = new CallbackTypeMapper(); - final Map _OPTIONS = new HashMap() { - { - put(Library.OPTION_TYPE_MAPPER, _MAPPER); - } - }; + final Map _OPTIONS = Collections.singletonMap(Library.OPTION_TYPE_MAPPER, _MAPPER); + interface DoubleCallback extends Callback { double callback(double arg, double arg2); } @@ -1040,31 +1108,31 @@ } protected CallbackTestLibrary loadCallbackTestLibrary() { - return (CallbackTestLibrary) - Native.loadLibrary("testlib", CallbackTestLibrary.class, CallbackTestLibrary._OPTIONS); + return Native.loadLibrary("testlib", CallbackTestLibrary.class, CallbackTestLibrary._OPTIONS); } /** This test is here instead of NativeTest in order to facilitate running the exact same test on a direct-mapped library without the tests interfering with one another due to persistent/cached state in library - loading. + loading. */ public void testCallbackUsesTypeMapper() throws Exception { CallbackTestLibrary lib = loadCallbackTestLibrary(); - lib._MAPPER.clear(); + CallbackTestLibrary._MAPPER.clear(); final double[] ARGS = new double[2]; CallbackTestLibrary.DoubleCallback cb = new CallbackTestLibrary.DoubleCallback() { + @Override public double callback(double arg, double arg2) { ARGS[0] = arg; ARGS[1] = arg2; return arg + arg2; } }; - assertEquals("Wrong type mapper for callback class", lib._MAPPER, + assertEquals("Wrong type mapper for callback class", CallbackTestLibrary._MAPPER, Native.getTypeMapper(CallbackTestLibrary.DoubleCallback.class)); - assertEquals("Wrong type mapper for callback object", lib._MAPPER, + assertEquals("Wrong type mapper for callback object", CallbackTestLibrary._MAPPER, Native.getTypeMapper(cb.getClass())); double result = lib.callInt32Callback(cb, -1, -2); @@ -1073,27 +1141,28 @@ assertEquals("Incorrect result of callback invocation", -3, result, 0); // Once per argument, then again for return value (convert native int->Java double) - assertEquals("Type mapper not called for arguments", 3, lib._MAPPER.fromNativeConversions); + assertEquals("Type mapper not called for arguments", 3, CallbackTestLibrary._MAPPER.fromNativeConversions); // Once per argument, then again for return value (convert Java double->native int) - assertEquals("Type mapper not called for result", 3, lib._MAPPER.toNativeConversions); + assertEquals("Type mapper not called for result", 3, CallbackTestLibrary._MAPPER.toNativeConversions); } public void testTypeMapperWithWideStrings() throws Exception { CallbackTestLibrary lib = loadCallbackTestLibrary(); - lib._MAPPER.clear(); + CallbackTestLibrary._MAPPER.clear(); final String[] ARGS = new String[2]; CallbackTestLibrary.WStringCallback cb = new CallbackTestLibrary.WStringCallback() { + @Override public String callback(String arg, String arg2) { ARGS[0] = arg; ARGS[1] = arg2; return arg + arg2; } }; - assertEquals("Wrong type mapper for callback class", lib._MAPPER, + assertEquals("Wrong type mapper for callback class", CallbackTestLibrary._MAPPER, Native.getTypeMapper(CallbackTestLibrary.WStringCallback.class)); - assertEquals("Wrong type mapper for callback object", lib._MAPPER, + assertEquals("Wrong type mapper for callback object", CallbackTestLibrary._MAPPER, Native.getTypeMapper(cb.getClass())); final String[] EXPECTED = { "magic" + UNICODE, getName() + UNICODE }; @@ -1103,9 +1172,9 @@ assertEquals("Incorrect result of callback invocation", EXPECTED[0] + EXPECTED[1], result); // Once per argument, then again for return value (convert const wchar_t*->Java String) - assertEquals("Type mapper not called for arguments", 3, lib._MAPPER.fromNativeConversions); + assertEquals("Type mapper not called for arguments", 3, CallbackTestLibrary._MAPPER.fromNativeConversions); // Once per argument, then again for return value (convert Java String->const wchar_t*) - assertEquals("Type mapper not called for result", 3, lib._MAPPER.toNativeConversions); + assertEquals("Type mapper not called for result", 3, CallbackTestLibrary._MAPPER.toNativeConversions); } public void testCallbackUsesTypeMapperWithDifferentReturnTypeSize() throws Exception { @@ -1114,15 +1183,16 @@ final float[] ARGS = new float[2]; CallbackTestLibrary.FloatCallback cb = new CallbackTestLibrary.FloatCallback() { + @Override public float callback(float arg, float arg2) { ARGS[0] = arg; ARGS[1] = arg2; return arg + arg2; } }; - assertEquals("Wrong type mapper for callback class", lib._MAPPER, + assertEquals("Wrong type mapper for callback class", CallbackTestLibrary._MAPPER, Native.getTypeMapper(CallbackTestLibrary.FloatCallback.class)); - assertEquals("Wrong type mapper for callback object", lib._MAPPER, + assertEquals("Wrong type mapper for callback object", CallbackTestLibrary._MAPPER, Native.getTypeMapper(cb.getClass())); float result = lib.callInt64Callback(cb, -1, -2); @@ -1165,6 +1235,7 @@ ThreadGroup testGroup = new ThreadGroup(getName() + UNICODE); TestLibrary.VoidCallback cb = new TestLibrary.VoidCallback() { + @Override public void callback() { Thread thread = Thread.currentThread(); daemon[0] = thread.isDaemon(); @@ -1193,6 +1264,7 @@ ThreadGroup testGroup = new ThreadGroup("Thread group for " + getName()); CallbackThreadInitializer init = new CallbackThreadInitializer(true, false, tname, testGroup); TestLibrary.VoidCallback cb = new TestLibrary.VoidCallback() { + @Override public void callback() { Thread thread = Thread.currentThread(); daemon[0] = thread.isDaemon(); @@ -1236,15 +1308,17 @@ // 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) { + @Override public String getName(Callback cb) { return "Test thread (native) for " + CallbacksTest.this.getName() + " (call count: " + called[0] + ")"; } }; TestLibrary.VoidCallback cb = new TestLibrary.VoidCallback() { + @Override public void callback() { threads.add(Thread.currentThread()); ++called[0]; @@ -1258,47 +1332,48 @@ assertEquals("Multiple callbacks on a given native thread should use the same Thread mapping: " + threads, 1, threads.size()); - waitFor((Thread)threads.iterator().next()); + waitFor(threads.iterator().next()); } // 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)"); } - Native.detach(false); + Native.detach(false); } }; - // Always attach as daemon to ensure tests will exit + // Always attach as daemon to ensure tests will exit CallbackThreadInitializer asDaemon = new CallbackThreadInitializer(true) { - public String getName(Callback cb) { - return "Test thread (native) for " + CallbacksTest.this.getName(); - } - }; + @Override + public String getName(Callback cb) { + return "Test thread (native) for " + CallbacksTest.this.getName(); + } + }; callThreadedCallback(cb, asDaemon, 2, 100, called); - // Wait for it to start up + // Wait for it to start up long start = System.currentTimeMillis(); while (threads.size() == 0 && called[0] == 0) { - Thread.sleep(10); - if (System.currentTimeMillis() - start > THREAD_TIMEOUT) { - fail("Timed out waiting for thread to detach and terminate"); - } + Thread.sleep(10L); + if (System.currentTimeMillis() - start > THREAD_TIMEOUT) { + fail("Timed out waiting for thread to detach and terminate"); + } } start = System.currentTimeMillis(); - WeakReference ref = (WeakReference)threads.iterator().next(); - + Reference ref = threads.iterator().next(); while (ref.get() != null) { System.gc(); Thread.sleep(100); - Thread[] remaining = new Thread[Thread.activeCount()]; - Thread.enumerate(remaining); + Thread[] remaining = new Thread[Thread.activeCount()]; + Thread.enumerate(remaining); if (System.currentTimeMillis() - start > THREAD_TIMEOUT) { - Thread t = (Thread)ref.get(); + Thread t = ref.get(); Pointer terminationFlag = Native.getTerminationFlag(t); assertNotNull("Native thread termination flag is missing", terminationFlag); if (terminationFlag.getInt(0) == 0) { @@ -1312,13 +1387,14 @@ } // Callback indicates detach preference (instead of - // CallbackThreadInitializer); thread is non-daemon (default), + // CallbackThreadInitializer); thread is non-daemon (default), // 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 public void callback() { threads.add(Thread.currentThread()); // detach on final invocation @@ -1338,7 +1414,7 @@ assertEquals("Multiple callbacks in the same native thread should use the same Thread mapping: " + threads, 1, threads.size()); - waitFor((Thread)threads.iterator().next()); + waitFor(threads.iterator().next()); } public void testDLLCallback() throws Exception { @@ -1348,6 +1424,7 @@ final boolean[] called = { false }; class TestCallback implements TestLibrary.VoidCallback, com.sun.jna.win32.DLLCallback { + @Override public void callback() { called[0] = true; } @@ -1363,7 +1440,7 @@ Function f = kernel32.getFunction("GetModuleHandleExW"); final int GET_MODULE_HANDLE_FROM_ADDRESS = 0x4; PointerByReference pref = new PointerByReference(); - int result = f.invokeInt(new Object[] { new Integer(GET_MODULE_HANDLE_FROM_ADDRESS), fp, pref }); + int result = f.invokeInt(new Object[] { Integer.valueOf(GET_MODULE_HANDLE_FROM_ADDRESS), fp, pref }); assertTrue("GetModuleHandleEx(fptr) failed: " + Native.getLastError(), result != 0); f = kernel32.getFunction("GetModuleFileNameW"); @@ -1377,13 +1454,13 @@ 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 = (CallbackReference)refs.get(cb); + CallbackReference ref = refs.get(cb); refs = callbackCache(); Pointer cbstruct = ref.cbstruct; Pointer first_fptr = cbstruct.getPointer(0); - + cb = null; System.gc(); for (int i = 0; i < 100 && (ref.get() != null || refs.containsValue(ref)); ++i) { @@ -1392,7 +1469,7 @@ } assertNull("Callback not GC'd", ref.get()); assertFalse("Callback still in map", refs.containsValue(ref)); - + ref = null; System.gc(); for (int i = 0; i < 100 && (cbstruct.peer != 0 || refs.size() > 0); ++i) { @@ -1408,7 +1485,7 @@ cb = new TestCallback(); lib.callVoidCallback(cb); - ref = (CallbackReference)refs.get(cb); + ref = refs.get(cb); cbstruct = ref.cbstruct; assertTrue("Callback not called", called[0]); @@ -1423,6 +1500,7 @@ final boolean[] called = { false }; class TestCallback implements TestLibrary.VoidCallback, com.sun.jna.win32.DLLCallback { + @Override public void callback() { called[0] = true; } @@ -1439,6 +1517,54 @@ } } + public interface TaggedCallingConventionTestLibrary extends Library, AltCallingConvention { + interface TestCallbackTagged extends Callback, AltCallingConvention { + void invoke(); + } + } + + public void testCallingConventionFromInterface() { + TaggedCallingConventionTestLibrary lib = Native.loadLibrary("testlib", TaggedCallingConventionTestLibrary.class); + TaggedCallingConventionTestLibrary.TestCallbackTagged cb = new TaggedCallingConventionTestLibrary.TestCallbackTagged() { + @Override + public void invoke() { } + }; + try { + Pointer p = CallbackReference.getFunctionPointer(cb); + CallbackReference ref = CallbackReference.callbackMap.get(cb); + assertNotNull("CallbackReference not found", ref); + assertEquals("Tag-based calling convention not applied", Function.ALT_CONVENTION, ref.callingConvention); + } + catch (IllegalArgumentException e) { + // Alt convention not supported + } + } + + public interface OptionCallingConventionTestLibrary extends Library { + interface TestCallback extends Callback { + void invoke(); + } + } + + public void testCallingConventionFromOptions() { + OptionCallingConventionTestLibrary lib = + Native.loadLibrary("testlib", OptionCallingConventionTestLibrary.class, Collections.singletonMap(Library.OPTION_CALLING_CONVENTION, Function.ALT_CONVENTION)); + assertNotNull("Library not loaded", lib); + OptionCallingConventionTestLibrary.TestCallback cb = new OptionCallingConventionTestLibrary.TestCallback() { + @Override + public void invoke() { } + }; + try { + Pointer p = CallbackReference.getFunctionPointer(cb); + assertNotNull("No function pointer", p); + CallbackReference ref = CallbackReference.callbackMap.get(cb); + assertNotNull("CallbackReference not found", ref); + assertEquals("Option-based calling convention not applied", Function.ALT_CONVENTION, ref.callingConvention); + } catch(IllegalArgumentException e) { + // Alt convention not supported + } + } + public static void main(java.lang.String[] argList) { junit.textui.TestRunner.run(CallbacksTest.class); } diff -Nru libjna-java-4.2.2/test/com/sun/jna/DirectArgumentsMarshalTest.java libjna-java-4.4.0/test/com/sun/jna/DirectArgumentsMarshalTest.java --- libjna-java-4.2.2/test/com/sun/jna/DirectArgumentsMarshalTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/DirectArgumentsMarshalTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,26 +1,28 @@ /* Copyright (c) 2009 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

        - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.nio.ByteBuffer; -import java.nio.FloatBuffer; -import java.nio.DoubleBuffer; -import java.nio.IntBuffer; -import java.nio.LongBuffer; -import java.nio.ShortBuffer; - -import com.sun.jna.ArgumentsMarshalTest.TestLibrary.CheckFieldAlignment.ByReference; - /** Exercise a range of native methods. * * @author twall@users.sf.net @@ -29,55 +31,92 @@ public static class DirectTestLibrary implements TestLibrary { /** Dummy. Automatically fail when passed an object. */ + @Override public String returnStringArgument(Object arg) {throw new IllegalArgumentException(arg.getClass().getName()); } + @Override public native boolean returnBooleanArgument(boolean arg); + @Override public native byte returnInt8Argument(byte arg); + @Override public native char returnWideCharArgument(char arg); + @Override public native short returnInt16Argument(short arg); + @Override public native int returnInt32Argument(int i); + @Override public native long returnInt64Argument(long l); + @Override public native NativeLong returnLongArgument(NativeLong l); + @Override public native float returnFloatArgument(float f); + @Override public native double returnDoubleArgument(double d); + @Override public native String returnStringArgument(String s); + @Override public native WString returnWStringArgument(WString s); + @Override public native Pointer returnPointerArgument(Pointer p); + @Override public String returnStringArrayElement(String[] args, int which) {throw new UnsupportedOperationException();} + @Override public WString returnWideStringArrayElement(WString[] args, int which) {throw new UnsupportedOperationException();} + @Override public Pointer returnPointerArrayElement(Pointer[] args, int which) {throw new UnsupportedOperationException();} + @Override public TestPointerType returnPointerArrayElement(TestPointerType[] args, int which) {throw new UnsupportedOperationException();} + @Override public CheckFieldAlignment returnPointerArrayElement(CheckFieldAlignment.ByReference[] args, int which) {throw new UnsupportedOperationException();} + @Override public int returnRotatedArgumentCount(String[] args) {throw new UnsupportedOperationException();} + @Override public native long checkInt64ArgumentAlignment(int i, long j, int i2, long j2); + @Override public native double checkDoubleArgumentAlignment(float i, double j, float i2, double j2); + @Override public native Pointer testStructurePointerArgument(CheckFieldAlignment p); + @Override public native int testStructureByValueArgument(CheckFieldAlignment.ByValue p); + @Override public int testStructureArrayInitialization(CheckFieldAlignment[] p, int len) { throw new UnsupportedOperationException(); } + @Override public int testStructureByReferenceArrayInitialization(CheckFieldAlignment.ByReference[] p, int len) { throw new UnsupportedOperationException(); } + @Override public void modifyStructureArray(CheckFieldAlignment[] p, int length) { - throw new UnsupportedOperationException(); + throw new UnsupportedOperationException(); } + @Override public void modifyStructureByReferenceArray(CheckFieldAlignment.ByReference[] p, int length) { - throw new UnsupportedOperationException(); + throw new UnsupportedOperationException(); } - + + @Override public native int fillInt8Buffer(byte[] buf, int len, byte value); + @Override public native int fillInt16Buffer(short[] buf, int len, short value); + @Override public native int fillInt32Buffer(int[] buf, int len, int value); + @Override public native int fillInt64Buffer(long[] buf, int len, long value); + @Override public native int fillFloatBuffer(float[] buf, int len, float value); + @Override public native int fillDoubleBuffer(double[] buf, int len, double value); // dummy to avoid causing Native.register to fail + @Override public boolean returnBooleanArgument(Object arg) {throw new IllegalArgumentException();} + @Override public native Pointer testStructurePointerArgument(MinTestStructure s); + @Override public native String returnStringFromVariableSizedStructure(VariableSizedStructure s); + @Override public native void setCallbackInStruct(CbStruct s); static { @@ -86,24 +125,30 @@ } /* Override original. */ + @Override protected void setUp() { lib = new DirectTestLibrary(); } - + public static class DirectNativeMappedLibrary implements NativeMappedLibrary { + @Override public native int returnInt32Argument(Custom arg); + @Override public native int returnInt32Argument(size_t arg); + @Override public native long returnInt64Argument(size_t arg); static { Native.register("testlib"); } } + @Override protected NativeMappedLibrary loadNativeMappedLibrary() { return new DirectNativeMappedLibrary(); } // This test crashes on w32 IBM J9 unless -Xint is used // (jvmwi3260-20080415_18762) + @Override public void testWideCharArgument() { if (Platform.isWindows() && "IBM".equals(System.getProperty("java.vm.vendor"))) { @@ -113,6 +158,7 @@ } // This test crashes on w32 IBM J9 unless -Xint is used // (jvmwi3260-20080415_18762) + @Override public void testWStringArgumentReturn() { if (Platform.isWindows() && "IBM".equals(System.getProperty("java.vm.vendor"))) { @@ -122,21 +168,33 @@ } // Override tests not yet supported in direct mode + @Override public void testStringArrayArgument() { } + @Override public void testWriteStructureArrayArgumentMemory() { } + @Override public void testUninitializedStructureArrayArgument() { } + @Override public void testRejectNoncontiguousStructureArrayArgument() { } + @Override public void testRejectIncompatibleStructureArrayArgument() { } + @Override public void testWideStringArrayArgument() { } + @Override public void testPointerArrayArgument() { } + @Override public void testNativeMappedArrayArgument() { } + @Override public void testStructureByReferenceArrayArgument() { } + @Override public void testWriteStructureByReferenceArrayArgumentMemory() { } + @Override public void testReadStructureByReferenceArrayArgumentMemory() { } + @Override public void testModifiedCharArrayArgument() { } public static void main(java.lang.String[] argList) { junit.textui.TestRunner.run(DirectArgumentsMarshalTest.class); } - + } diff -Nru libjna-java-4.2.2/test/com/sun/jna/DirectBufferArgumentsMarshalTest.java libjna-java-4.4.0/test/com/sun/jna/DirectBufferArgumentsMarshalTest.java --- libjna-java-4.2.2/test/com/sun/jna/DirectBufferArgumentsMarshalTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/DirectBufferArgumentsMarshalTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,26 +1,35 @@ /* Copyright (c) 2009 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

        - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.nio.ByteBuffer; -import java.nio.FloatBuffer; import java.nio.DoubleBuffer; +import java.nio.FloatBuffer; import java.nio.IntBuffer; import java.nio.LongBuffer; import java.nio.ShortBuffer; -import com.sun.jna.ArgumentsMarshalTest.TestLibrary.CheckFieldAlignment.ByReference; - /** Exercise a range of native methods. * * @author twall@users.sf.net @@ -30,18 +39,29 @@ public static class DirectTestLibrary implements TestLibrary { // ByteBuffer alternative definitions + @Override public native int fillInt8Buffer(ByteBuffer buf, int len, byte value); + @Override public native int fillInt16Buffer(ByteBuffer buf, int len, short value); + @Override public native int fillInt32Buffer(ByteBuffer buf, int len, int value); + @Override public native int fillInt64Buffer(ByteBuffer buf, int len, long value); + @Override public native int fillFloatBuffer(ByteBuffer buf, int len, float value); + @Override public native int fillDoubleBuffer(ByteBuffer buf, int len, double value); - - // {Short|Int|Long|Float|Double}Buffer alternative definitions + + // {Short|Int|Long|Float|Double}Buffer alternative definitions + @Override public native int fillInt16Buffer(ShortBuffer buf, int len, short value); + @Override public native int fillInt32Buffer(IntBuffer buf, int len, int value); + @Override public native int fillInt64Buffer(LongBuffer buf, int len, long value); + @Override public native int fillFloatBuffer(FloatBuffer buf, int len, float value); + @Override public native int fillDoubleBuffer(DoubleBuffer buf, int len, double value); static { @@ -50,12 +70,13 @@ } /* Override original. */ + @Override protected void setUp() { lib = new DirectTestLibrary(); } - + public static void main(java.lang.String[] argList) { junit.textui.TestRunner.run(DirectBufferArgumentsMarshalTest.class); } - + } diff -Nru libjna-java-4.2.2/test/com/sun/jna/DirectByReferenceArgumentsTest.java libjna-java-4.4.0/test/com/sun/jna/DirectByReferenceArgumentsTest.java --- libjna-java-4.2.2/test/com/sun/jna/DirectByReferenceArgumentsTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/DirectByReferenceArgumentsTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2009 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

        - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; diff -Nru libjna-java-4.2.2/test/com/sun/jna/DirectCallbacksTest.java libjna-java-4.4.0/test/com/sun/jna/DirectCallbacksTest.java --- libjna-java-4.2.2/test/com/sun/jna/DirectCallbacksTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/DirectCallbacksTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2009 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

        - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; @@ -23,29 +34,52 @@ public class DirectCallbacksTest extends CallbacksTest { public static class DirectTestLibrary implements TestLibrary { + @Override public native void callVoidCallback(VoidCallbackCustom c); + @Override public native boolean callBooleanCallback(BooleanCallback c, boolean arg, boolean arg2); + @Override public native byte callInt8Callback(ByteCallback c, byte arg, byte arg2); + @Override public native short callInt16Callback(ShortCallback c, short arg, short arg2); + @Override public native int callInt32Callback(Int32Callback c, int arg, int arg2); + @Override public native NativeLong callNativeLongCallback(NativeLongCallback c, NativeLong arg, NativeLong arg2); + @Override public native long callInt64Callback(Int64Callback c, long arg, long arg2); + @Override public native float callFloatCallback(FloatCallback c, float arg, float arg2); + @Override public native double callDoubleCallback(DoubleCallback c, double arg, double arg2); + @Override public native SmallTestStructure callStructureCallback(StructureCallback c, SmallTestStructure arg); + @Override public native String callStringCallback(StringCallback c, String arg, String arg2); + @Override public native WString callWideStringCallback(WideStringCallback c, WString arg, WString arg2); + @Override public Pointer callStringArrayCallback(StringArrayCallback c, String[] arg) { throw new UnsupportedOperationException(); } + @Override public native int callCallbackWithByReferenceArgument(CopyArgToByReference cb, int arg, IntByReference result); + @Override public native TestStructure.ByValue callCallbackWithStructByValue(TestStructure.TestCallback callback, TestStructure.ByValue cbstruct); + @Override public native CbCallback callCallbackWithCallback(CbCallback cb); + @Override public native Int32CallbackX returnCallback(); + @Override public native Int32CallbackX returnCallbackArgument(Int32CallbackX cb); + @Override public native void callVoidCallback(VoidCallback c); + @Override public native void callVoidCallbackThreaded(VoidCallback c, int count, int ms, String name); + @Override public native int callInt32Callback(CustomCallback cb, int arg1, int arg2); + @Override public native void callCallbackInStruct(CbStruct s); + @Override public native TestUnion testUnionByValueCallbackArgument(UnionCallback cb, TestUnion arg); static { @@ -53,29 +87,37 @@ } } + @Override protected void setUp() { lib = new DirectTestLibrary(); } - - protected Map callbackCache() { + + @Override + protected Map callbackCache() { return CallbackReference.directCallbackMap; } public static class DirectCallbackTestLibrary implements CallbackTestLibrary { + @Override public native double callInt32Callback(DoubleCallback c, double arg, double arg2); + @Override public native float callInt64Callback(FloatCallback c, float arg, float arg2); + @Override public native String callWideStringCallback(WStringCallback c, String arg, String arg2); static { Native.register(NativeLibrary.getInstance("testlib", _OPTIONS)); } } + @Override protected CallbackTestLibrary loadCallbackTestLibrary() { return new DirectCallbackTestLibrary(); } // Currently unsupported tests + @Override public void testCallStringArrayCallback() { } + @Override public void testCallbackExceptionHandlerWithCallbackProxy() { } public static void main(java.lang.String[] argList) { diff -Nru libjna-java-4.2.2/test/com/sun/jna/DirectReturnTypesTest.java libjna-java-4.4.0/test/com/sun/jna/DirectReturnTypesTest.java --- libjna-java-4.2.2/test/com/sun/jna/DirectReturnTypesTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/DirectReturnTypesTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,26 +1,30 @@ /* Copyright (c) 2009 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

        - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.HashMap; import java.util.Map; -import junit.framework.TestCase; - -import com.sun.jna.ReturnTypesTest.TestLibrary.SimpleStructure; -import com.sun.jna.ReturnTypesTest.TestLibrary.TestStructure; -import com.sun.jna.ReturnTypesTest.TestLibrary.TestSmallStructure; - /** Exercise a range of native methods. * * @author twall@users.sf.net @@ -28,34 +32,57 @@ public class DirectReturnTypesTest extends ReturnTypesTest { public static class DirectTestLibrary implements TestLibrary { - + + @Override public Object returnObjectArgument(Object s) { throw new IllegalArgumentException(s.getClass().getName()); } + @Override public TestObject returnObjectArgument(TestObject s) { throw new IllegalArgumentException(s.getClass().getName()); } + @Override public native boolean returnFalse(); + @Override public native boolean returnTrue(); + @Override public native int returnInt32Zero(); + @Override public native int returnInt32Magic(); + @Override public native long returnInt64Zero(); + @Override public native long returnInt64Magic(); + @Override public native NativeLong returnLongZero(); + @Override public native NativeLong returnLongMagic(); + @Override public native float returnFloatZero(); + @Override public native float returnFloatMagic(); + @Override public native double returnDoubleZero(); + @Override public native double returnDoubleMagic(); + @Override public native String returnStringMagic(); + @Override public native WString returnWStringMagic(); + @Override public native SimpleStructure returnStaticTestStructure(); + @Override public native SimpleStructure returnNullTestStructure(); + @Override public native TestSmallStructure.ByValue returnSmallStructureByValue(); + @Override public native TestStructure.ByValue returnStructureByValue(); + @Override public Pointer[] returnPointerArgument(Pointer[] arg) {throw new UnsupportedOperationException();} + @Override public String[] returnPointerArgument(String[] arg) {throw new UnsupportedOperationException();} + @Override public WString[] returnPointerArgument(WString[] arg) {throw new UnsupportedOperationException();} static { @@ -63,32 +90,41 @@ } } + @Override protected void setUp() { lib = new DirectTestLibrary(); } - + public static class DirectObjectTestLibrary extends DirectTestLibrary { - public DirectObjectTestLibrary(Map options) { + public DirectObjectTestLibrary(Map options) { Native.register(getClass(), NativeLibrary.getInstance("testlib", options)); } } public static class DirectNativeMappedLibrary implements NativeMappedLibrary { + @Override public native Custom returnInt32Argument(int arg); + @Override public native size_t returnInt32Magic(); + @Override public native size_t returnInt64Magic(); static { Native.register("testlib"); } } + @Override protected NativeMappedLibrary loadNativeMappedLibrary() { return new DirectNativeMappedLibrary(); } // Override not-yet-supported tests + @Override public void testReturnObject() { } + @Override public void testReturnPointerArray() { } + @Override public void testReturnStringArray() { } + @Override public void testReturnWStringArray() { } public static void main(java.lang.String[] argList) { diff -Nru libjna-java-4.2.2/test/com/sun/jna/DirectStructureByValueTest.java libjna-java-4.4.0/test/com/sun/jna/DirectStructureByValueTest.java --- libjna-java-4.2.2/test/com/sun/jna/DirectStructureByValueTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/DirectStructureByValueTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,23 +1,28 @@ /* Copyright (c) 2009 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

        - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.nio.Buffer; -import java.nio.ByteBuffer; -import java.util.Map; - -import junit.framework.TestCase; - /** General structure by value functionality tests. */ public class DirectStructureByValueTest extends StructureByValueTest { diff -Nru libjna-java-4.2.2/test/com/sun/jna/DirectTest.java libjna-java-4.4.0/test/com/sun/jna/DirectTest.java --- libjna-java-4.2.2/test/com/sun/jna/DirectTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/DirectTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,27 +1,36 @@ /* Copyright (c) 2009 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

        - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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 junit.framework.*; -import com.sun.jna.*; -import com.sun.jna.ptr.PointerByReference; -import java.lang.ref.*; import java.lang.reflect.Method; import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -36,7 +45,7 @@ static class MathLibrary { public static native double cos(double x); - + static { Native.register(Platform.MATH_LIBRARY_NAME); } @@ -48,6 +57,8 @@ static class CLibrary { public static class size_t extends IntegerType { + private static final long serialVersionUID = 1L; + public size_t() { super(Native.POINTER_SIZE); } @@ -64,7 +75,7 @@ public static native int strlen(String s1); public static native int strlen(Pointer p); public static native int strlen(byte[] b); - + static { Native.register(Platform.C_LIBRARY_NAME); } @@ -87,7 +98,9 @@ } static class TestLibrary implements TestInterface { + @Override public native int callInt32CallbackRepeatedly(Int32Callback cb, int arg1, int arg2, int count); + @Override public native NativeLong callLongCallbackRepeatedly(NativeLongCallback cb, NativeLong arg1, NativeLong arg2, int count); static { Native.register("testlib"); @@ -98,6 +111,7 @@ public TestLoader() throws MalformedURLException { this(null); } + public TestLoader(ClassLoader parent) throws MalformedURLException { super(Platform.isWindowsCE() ? new URL[] { @@ -108,12 +122,13 @@ new File(BUILDDIR + "/test-classes").toURI().toURL(), }, new CloverLoader(parent)); } - protected Class findClass(String name) throws ClassNotFoundException { + @Override + protected Class findClass(String name) throws ClassNotFoundException { String boot = System.getProperty("jna.boot.library.path"); if (boot != null) { System.setProperty("jna.boot.library.path", ""); } - Class cls = super.findClass(name); + Class cls = super.findClass(name); if (boot != null) { System.setProperty("jna.boot.library.path", boot); } @@ -130,7 +145,7 @@ Native.registered(MathLibrary.class)); } - private Class returnCallingClass() { + private Class returnCallingClass() { return Native.getCallingClass(); } @@ -142,15 +157,15 @@ public void testFindNativeClass() { class UnregisterLibrary { class Inner { - public Class findDirectMappedClass() { + public Class findDirectMappedClass() { return findDirectMappedClassInner(); } - public Class findDirectMappedClassInner() { + public Class findDirectMappedClassInner() { return Native.findDirectMappedClass(Native.getCallingClass()); }; } public native double cos(double x); - public Class findDirectMappedClass() { + public Class findDirectMappedClass() { return new Inner().findDirectMappedClass(); }; } @@ -161,20 +176,21 @@ public static class DirectMapping { public static class DirectStructure extends Structure { public int field; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "field" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("field"); } } public static interface DirectCallback extends Callback { void invoke(); } - public DirectMapping(Map options) { + public DirectMapping(Map options) { Native.register(getClass(), NativeLibrary.getInstance("testlib", options)); } } public void testGetOptionsForDirectMappingWithMemberInitializer() { - Class[] classes = { + Class[] classes = { DirectMapping.class, DirectMapping.DirectStructure.class, DirectMapping.DirectCallback.class, @@ -182,20 +198,20 @@ final TypeMapper mapper = new DefaultTypeMapper(); final int alignment = Structure.ALIGN_NONE; final String encoding = System.getProperty("file.encoding"); - Map options = new HashMap(); + 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); DirectMapping lib = new DirectMapping(options); - for (int i=0;i < classes.length;i++) { - assertEquals("Wrong type mapper for direct mapping " + classes[i], - mapper, Native.getTypeMapper(classes[i])); - assertEquals("Wrong alignment for direct mapping " + classes[i], - alignment, Native.getStructureAlignment(classes[i])); - assertEquals("Wrong encoding for direct mapping " + classes[i], - encoding, Native.getStringEncoding(classes[i])); - Object last = Native.getLibraryOptions(classes[i]);; - assertSame("Options not cached", last, Native.getLibraryOptions(classes[i])); + for (Class cls : classes) { + assertEquals("Wrong type mapper for direct mapping " + cls, + mapper, Native.getTypeMapper(cls)); + assertEquals("Wrong alignment for direct mapping " + cls, + alignment, Native.getStructureAlignment(cls)); + assertEquals("Wrong encoding for direct mapping " + cls, + encoding, Native.getStringEncoding(cls)); + Object last = Native.getLibraryOptions(cls); + assertSame("Options not cached", last, Native.getLibraryOptions(cls)); } } @@ -203,7 +219,9 @@ 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 Map TEST_OPTIONS = new HashMap() { + final static Map TEST_OPTIONS = new HashMap() { + private static final long serialVersionUID = 1L; // we're not serializing it + { put(Library.OPTION_TYPE_MAPPER, TEST_MAPPER); put(Library.OPTION_STRUCTURE_ALIGNMENT, TEST_ALIGNMENT); @@ -215,8 +233,9 @@ } public static class DirectStructure extends Structure { public int field; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "field" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("field"); } } public static interface DirectCallback extends Callback { @@ -225,20 +244,20 @@ } public void testGetOptionsForDirectMappingWithStaticInitializer() { - Class[] classes = { + Class[] classes = { DirectMappingStatic.class, DirectMappingStatic.DirectStructure.class, DirectMappingStatic.DirectCallback.class, }; - for (int i=0;i < classes.length;i++) { - assertEquals("Wrong type mapper for direct mapping " + classes[i], - DirectMappingStatic.TEST_MAPPER, Native.getTypeMapper(classes[i])); - assertEquals("Wrong alignment for direct mapping " + classes[i], - DirectMappingStatic.TEST_ALIGNMENT, Native.getStructureAlignment(classes[i])); - assertEquals("Wrong encoding for direct mapping " + classes[i], - DirectMappingStatic.TEST_ENCODING, Native.getStringEncoding(classes[i])); - Object last = Native.getLibraryOptions(classes[i]);; - assertSame("Options not cached", last, Native.getLibraryOptions(classes[i])); + for (Class cls : classes) { + assertEquals("Wrong type mapper for direct mapping " + cls, + DirectMappingStatic.TEST_MAPPER, Native.getTypeMapper(cls)); + assertEquals("Wrong alignment for direct mapping " + cls, + DirectMappingStatic.TEST_ALIGNMENT, Native.getStructureAlignment(cls)); + assertEquals("Wrong encoding for direct mapping " + cls, + DirectMappingStatic.TEST_ENCODING, Native.getStringEncoding(cls)); + Object last = Native.getLibraryOptions(cls); + assertSame("Options not cached", last, Native.getLibraryOptions(cls)); } } @@ -249,6 +268,7 @@ public void testDirectMappingFunctionMapper() { FunctionMapper MAPPER = new FunctionMapper() { + @Override public String getFunctionName(NativeLibrary lib, Method method) { String name = method.getName(); if (name.startsWith("_prefixed_")) { @@ -257,23 +277,68 @@ return name; } }; - Map options = new HashMap(); - options.put(Library.OPTION_FUNCTION_MAPPER, MAPPER); + try { Native.register(RemappedCLibrary.class, - NativeLibrary.getInstance(Platform.C_LIBRARY_NAME, options)); + NativeLibrary.getInstance(Platform.C_LIBRARY_NAME, Collections.singletonMap(Library.OPTION_FUNCTION_MAPPER, MAPPER))); final String VALUE = getName(); int len; len = RemappedCLibrary.$$YJP$$strlen(VALUE); - assertEquals(VALUE.length(), len); + assertEquals("Mismatched YJP strlen value", VALUE.length(), len); len = RemappedCLibrary._prefixed_strlen(VALUE); - assertEquals(VALUE.length(), len); - } - catch(Exception e) { + assertEquals("Mismatched prefixed strlen value", VALUE.length(), len); + } catch(Exception e) { fail("Native method was not properly mapped: " + e); } } + + public static class PointerNativeMapped implements NativeMapped { + String nativeMethodName; + @Override + public PointerNativeMapped fromNative(Object nativeValue, FromNativeContext context) { + nativeMethodName = ((MethodResultContext)context).getMethod().getName(); + return this; + } + @Override + public Object toNative() { + return null; + } + @Override + public Class nativeType() { + return Pointer.class; + } + } + public static class PointerTypeMapped { + String nativeMethodName; + } + public static class FromNativeTests { + static native PointerNativeMapped returnPointerArgument(PointerNativeMapped arg); + static native PointerTypeMapped returnPointerArgument(PointerTypeMapped arg); + } + public void testDirectMappingFromNative() { + DefaultTypeMapper mapper = new DefaultTypeMapper(); + mapper.addTypeConverter(PointerTypeMapped.class, new TypeConverter() { + @Override + public PointerTypeMapped fromNative(Object nativeValue, FromNativeContext context) { + PointerTypeMapped ret = new PointerTypeMapped(); + ret.nativeMethodName = ((MethodResultContext)context).getMethod().getName(); + return ret; + } + @Override + public Object toNative(Object value, ToNativeContext context) { + return null; + } + @Override + public Class nativeType() { + return Pointer.class; + } + }); + NativeLibrary lib = NativeLibrary.getInstance("testlib", Collections.singletonMap(Library.OPTION_TYPE_MAPPER, mapper)); + Native.register(FromNativeTests.class, lib); + assertEquals("Failed to access MethodResultContext", "returnPointerArgument", FromNativeTests.returnPointerArgument(new PointerNativeMapped()).nativeMethodName); + assertEquals("Failed to access MethodResultContext", "returnPointerArgument", FromNativeTests.returnPointerArgument(new PointerTypeMapped()).nativeMethodName); + } } diff -Nru libjna-java-4.2.2/test/com/sun/jna/DirectTypeMapperTest.java libjna-java-4.4.0/test/com/sun/jna/DirectTypeMapperTest.java --- libjna-java-4.2.2/test/com/sun/jna/DirectTypeMapperTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/DirectTypeMapperTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,20 +1,30 @@ /* Copyright (c) 2009 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

        - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.HashMap; -import java.util.Map; +import java.util.Collections; import junit.framework.TestCase; public class DirectTypeMapperTest extends TestCase { @@ -26,18 +36,19 @@ final static int MAGIC = 0xABEDCF23; public native int returnInt32Argument(boolean b); static { - Map options = new HashMap(); DefaultTypeMapper mapper = new DefaultTypeMapper(); mapper.addToNativeConverter(Boolean.class, new ToNativeConverter() { + @Override public Object toNative(Object arg, ToNativeContext ctx) { - return new Integer(Boolean.TRUE.equals(arg) ? MAGIC : 0); + return Integer.valueOf(Boolean.TRUE.equals(arg) ? MAGIC : 0); } - public Class nativeType() { + @Override + public Class nativeType() { return Integer.class; } }); - options.put(Library.OPTION_TYPE_MAPPER, mapper); - Native.register(NativeLibrary.getInstance("testlib", options)); + + Native.register(NativeLibrary.getInstance("testlib", Collections.singletonMap(Library.OPTION_TYPE_MAPPER, mapper))); } } /** Converts String to int when going to native. */ @@ -46,16 +57,16 @@ static { DefaultTypeMapper mapper = new DefaultTypeMapper(); mapper.addToNativeConverter(String.class, new ToNativeConverter() { + @Override public Object toNative(Object arg, ToNativeContext ctx) { return Integer.valueOf((String) arg, 16); } - public Class nativeType() { + @Override + public Class nativeType() { return Integer.class; } }); - Map options = new HashMap(); - options.put(Library.OPTION_TYPE_MAPPER, mapper); - Native.register(NativeLibrary.getInstance("testlib", options)); + Native.register(NativeLibrary.getInstance("testlib", Collections.singletonMap(Library.OPTION_TYPE_MAPPER, mapper))); } } /** Converts CharSequence to int when going to native. */ @@ -64,17 +75,16 @@ static { DefaultTypeMapper mapper = new DefaultTypeMapper(); mapper.addToNativeConverter(CharSequence.class, new ToNativeConverter() { + @Override public Object toNative(Object arg, ToNativeContext ctx) { return Integer.valueOf(((CharSequence)arg).toString(), 16); } - public Class nativeType() { + @Override + public Class nativeType() { return Integer.class; } }); - Map options = new HashMap(); - options.put(Library.OPTION_TYPE_MAPPER, mapper); - - Native.register(NativeLibrary.getInstance("testlib", options)); + Native.register(NativeLibrary.getInstance("testlib", Collections.singletonMap(Library.OPTION_TYPE_MAPPER, mapper))); } } /** Converts Number to int when going to native. */ @@ -83,17 +93,16 @@ static { DefaultTypeMapper mapper = new DefaultTypeMapper(); mapper.addToNativeConverter(Number.class, new ToNativeConverter() { + @Override public Object toNative(Object arg, ToNativeContext ctx) { - return new Integer(((Number)arg).intValue()); + return Integer.valueOf(((Number)arg).intValue()); } - public Class nativeType() { + @Override + public Class nativeType() { return Integer.class; } }); - Map options = new HashMap(); - options.put(Library.OPTION_TYPE_MAPPER, mapper); - - Native.register(NativeLibrary.getInstance("testlib", options)); + Native.register(NativeLibrary.getInstance("testlib", Collections.singletonMap(Library.OPTION_TYPE_MAPPER, mapper))); } } /** Converts String to WString and back. */ @@ -102,32 +111,32 @@ static { DefaultTypeMapper mapper = new DefaultTypeMapper(); mapper.addTypeConverter(String.class, new TypeConverter() { + @Override public Object toNative(Object value, ToNativeContext ctx) { if (value == null) { return null; } return new WString(value.toString()); } + @Override public Object fromNative(Object value, FromNativeContext context) { if (value == null) { return null; } return value.toString(); } - public Class nativeType() { + @Override + public Class nativeType() { return WString.class; } }); - Map options = new HashMap(); - options.put(Library.OPTION_TYPE_MAPPER, mapper); - - Native.register(NativeLibrary.getInstance("testlib", options)); + Native.register(NativeLibrary.getInstance("testlib", Collections.singletonMap(Library.OPTION_TYPE_MAPPER, mapper))); } } public void testBooleanToIntArgumentConversion() { DirectTestLibraryBoolean lib = new DirectTestLibraryBoolean(); assertEquals("Failed to convert Boolean argument to Int", - lib.MAGIC, + DirectTestLibraryBoolean.MAGIC, lib.returnInt32Argument(true)); } public void testStringToIntArgumentConversion() { @@ -143,11 +152,11 @@ lib.returnInt32Argument(Integer.toHexString(MAGIC))); } public void testNumberToIntArgumentConversion() { - + final int MAGIC = 0x7BEDCF23; DirectTestLibraryNumber lib = new DirectTestLibraryNumber(); assertEquals("Failed to convert Double argument to Int", MAGIC, - lib.returnInt32Argument(new Double(MAGIC))); + lib.returnInt32Argument(Double.valueOf(MAGIC))); } public void testStringToWStringArgumentConversion() { final String MAGIC = "magic" + UNICODE; @@ -161,36 +170,38 @@ public native boolean returnInt32Argument(boolean b); static { final int MAGIC = 0xABEDCF23; - Map options = new HashMap(); DefaultTypeMapper mapper = new DefaultTypeMapper(); // Use opposite sense of default int<-->boolean conversions mapper.addToNativeConverter(Boolean.class, new ToNativeConverter() { + @Override public Object toNative(Object value, ToNativeContext ctx) { - return new Integer(Boolean.TRUE.equals(value) ? 0 : MAGIC); + return Integer.valueOf(Boolean.TRUE.equals(value) ? 0 : MAGIC); } - public Class nativeType() { + @Override + public Class nativeType() { return Integer.class; } }); mapper.addFromNativeConverter(Boolean.class, new FromNativeConverter() { + @Override public Object fromNative(Object value, FromNativeContext context) { return Boolean.valueOf(((Integer) value).intValue() != MAGIC); } - public Class nativeType() { + @Override + public Class nativeType() { return Integer.class; } }); - options.put(Library.OPTION_TYPE_MAPPER, mapper); - Native.register(NativeLibrary.getInstance("testlib", options)); + Native.register(NativeLibrary.getInstance("testlib", Collections.singletonMap(Library.OPTION_TYPE_MAPPER, mapper))); } } public void testIntegerToBooleanResultConversion() throws Exception { DirectTestLibraryBidirectionalBoolean lib = new DirectTestLibraryBidirectionalBoolean(); // argument "true" converts to zero; result zero converts to "true" - assertTrue("Failed to convert integer return to boolean TRUE", + assertTrue("Failed to convert integer return to boolean TRUE", lib.returnInt32Argument(true)); // argument "true" converts to MAGIC; result MAGIC converts to "false" - assertFalse("Failed to convert integer return to boolean FALSE", + assertFalse("Failed to convert integer return to boolean FALSE", lib.returnInt32Argument(false)); } public static class PointTestClass { @@ -200,9 +211,9 @@ public static class DirectTypeMappedResultTypeTestLibrary { public native PointTestClass returnPoint(int x, int y); static { - Map options = new HashMap(); DefaultTypeMapper mapper = new DefaultTypeMapper(); mapper.addTypeConverter(PointTestClass.class, new TypeConverter() { + @Override public Object fromNative(Object value, FromNativeContext context) { Pointer p = (Pointer) value; PointTestClass pc = new PointTestClass(); @@ -211,16 +222,18 @@ Native.free(Pointer.nativeValue(p)); return pc; } + @Override public Object toNative(Object value, ToNativeContext context) { return Pointer.NULL; // dummy implementation (not called) } - public Class nativeType() { + @Override + public Class nativeType() { return Pointer.class; } }); - options.put(Library.OPTION_TYPE_MAPPER, mapper); + PointTestClass.TYPE_MAPPER = mapper; - Native.register(NativeLibrary.getInstance("testlib", options)); + Native.register(NativeLibrary.getInstance("testlib", Collections.singletonMap(Library.OPTION_TYPE_MAPPER, mapper))); } } public void testTypeMapperResultTypeConversion() throws Exception { @@ -247,20 +260,20 @@ static { DefaultTypeMapper mapper = new DefaultTypeMapper(); mapper.addTypeConverter(Enumeration.class, new TypeConverter() { + @Override public Object toNative(Object arg, ToNativeContext ctx) { - return new Integer(((Enumeration)arg).getCode()); + return Integer.valueOf(((Enumeration)arg).getCode()); } + @Override public Object fromNative(Object value, FromNativeContext context) { return Enumeration.fromCode(((Integer)value).intValue()); } - public Class nativeType() { + @Override + public Class nativeType() { return Integer.class; } }); - Map options = new HashMap(); - options.put(Library.OPTION_TYPE_MAPPER, mapper); - - Native.register(NativeLibrary.getInstance("testlib", options)); + Native.register(NativeLibrary.getInstance("testlib", Collections.singletonMap(Library.OPTION_TYPE_MAPPER, mapper))); } } public void testEnumerationConversion() { diff -Nru libjna-java-4.2.2/test/com/sun/jna/ELFAnalyserTest.java libjna-java-4.4.0/test/com/sun/jna/ELFAnalyserTest.java --- libjna-java-4.2.2/test/com/sun/jna/ELFAnalyserTest.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/ELFAnalyserTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,108 @@ + +package com.sun.jna; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import org.junit.AfterClass; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import org.junit.BeforeClass; +import org.junit.Test; + + +public class ELFAnalyserTest { + + + private static File testResources = new File("build/test-resources"); + private static File win32Lib = new File(testResources, "win32-x86-64.dll"); + private static File linuxArmelLib = new File(testResources, "linux-armel.so"); + private static File linuxArmhfLib = new File(testResources, "linux-armhf.so"); + private static File linuxAmd64Lib = new File(testResources, "linux-amd64.so"); + + @BeforeClass + public static void initClass() throws IOException { + File win32Zip = new File("lib/native/win32-x86-64.jar"); + File linuxArmelZip = new File("lib/native/linux-armel.jar"); + File linuxArmhfZip = new File("lib/native/linux-arm.jar"); + File linuxAmd64Zip = new File("lib/native/linux-x86-64.jar"); + + testResources.mkdirs(); + + extractFileFromZip(win32Zip, "jnidispatch.dll", win32Lib); + extractFileFromZip(linuxArmelZip, "libjnidispatch.so", linuxArmelLib); + extractFileFromZip(linuxArmhfZip, "libjnidispatch.so", linuxArmhfLib); + extractFileFromZip(linuxAmd64Zip, "libjnidispatch.so", linuxAmd64Lib); + } + + @Test + public void testNonELF() throws IOException { + ELFAnalyser ahfd = ELFAnalyser.analyse(win32Lib.getAbsolutePath()); + assertFalse(ahfd.isELF()); + } + + @Test + public void testNonArm() throws IOException { + ELFAnalyser ahfd = ELFAnalyser.analyse(linuxAmd64Lib.getAbsolutePath()); + assertTrue(ahfd.isELF()); + assertFalse(ahfd.isArm()); + assertTrue(ahfd.is64Bit()); + } + + @Test + public void testArmhf() throws IOException { + ELFAnalyser ahfd = ELFAnalyser.analyse(linuxArmhfLib.getAbsolutePath()); + assertTrue(ahfd.isELF()); + assertTrue(ahfd.isArm()); + assertFalse(ahfd.is64Bit()); + assertFalse(ahfd.isArmSoftFloat()); + assertTrue(ahfd.isArmHardFloat()); + } + + @Test + public void testArmel() throws IOException { + ELFAnalyser ahfd = ELFAnalyser.analyse(linuxArmelLib.getAbsolutePath()); + assertTrue(ahfd.isELF()); + assertTrue(ahfd.isArm()); + assertFalse(ahfd.is64Bit()); + assertTrue(ahfd.isArmSoftFloat()); + assertFalse(ahfd.isArmHardFloat()); + } + + @AfterClass + public static void afterClass() throws IOException { + linuxAmd64Lib.delete(); + linuxArmhfLib.delete(); + linuxArmelLib.delete(); + win32Lib.delete(); + testResources.delete(); + } + + private static void extractFileFromZip(File zipTarget, String zipEntryName, File outputFile) throws IOException { + ZipFile zip = new ZipFile(zipTarget); + try { + ZipEntry entry = zip.getEntry(zipEntryName); + if(entry == null) { + throw new IOException("ZipEntry for name " + zipEntryName + " not found in " + zipTarget.getAbsolutePath()); + } + InputStream is = zip.getInputStream(entry); // Implicitly closed by closing ZipFile + OutputStream os = new FileOutputStream(outputFile); + try { + int read; + byte[] buffer = new byte[1024 * 1024]; + while((read = is.read(buffer)) > 0) { + os.write(buffer, 0, read); + } + } finally { + os.close(); + } + } finally { + zip.close(); + } + } +} + diff -Nru libjna-java-4.2.2/test/com/sun/jna/FunctionTest.java libjna-java-4.4.0/test/com/sun/jna/FunctionTest.java --- libjna-java-4.2.2/test/com/sun/jna/FunctionTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/FunctionTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,20 +1,28 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

        - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.Arrays; -import java.util.List; - import junit.framework.TestCase; /** Exercise the {@link Function} class. @@ -30,11 +38,11 @@ Object[] args = new Object[Function.MAX_NARGS+1]; // Make sure we don't break 'printf' args[0] = getName(); - try { + try { f.invokeInt(args); fail("Arguments should be limited to " + Function.MAX_NARGS); - } - catch(UnsupportedOperationException e) { + } catch(UnsupportedOperationException e) { + // expected } assertEquals("Wrong result from 'printf'", getName().length(), f.invokeInt(new Object[] { getName() })); } @@ -45,13 +53,13 @@ try { f.invoke(getClass(), new Object[] { getName() }); fail("Invalid return types should throw an exception"); - } - catch(IllegalArgumentException e) { + } catch(IllegalArgumentException e) { + // expected } } public static void main(java.lang.String[] argList) { junit.textui.TestRunner.run(FunctionTest.class); } - + } diff -Nru libjna-java-4.2.2/test/com/sun/jna/GCWaits.java libjna-java-4.4.0/test/com/sun/jna/GCWaits.java --- libjna-java-4.2.2/test/com/sun/jna/GCWaits.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/GCWaits.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,3 +1,27 @@ +/* Copyright (c) 2007 Timothy Wall, 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; public interface GCWaits { diff -Nru libjna-java-4.2.2/test/com/sun/jna/HeadlessLoadLibraryTest.java libjna-java-4.4.0/test/com/sun/jna/HeadlessLoadLibraryTest.java --- libjna-java-4.2.2/test/com/sun/jna/HeadlessLoadLibraryTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/HeadlessLoadLibraryTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,3 +1,25 @@ +/* + * 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 junit.framework.TestCase; diff -Nru libjna-java-4.2.2/test/com/sun/jna/IntegerTypeTest.java libjna-java-4.4.0/test/com/sun/jna/IntegerTypeTest.java --- libjna-java-4.2.2/test/com/sun/jna/IntegerTypeTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/IntegerTypeTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,3 +1,25 @@ +/** + * 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.Arrays; @@ -8,6 +30,7 @@ public class IntegerTypeTest extends TestCase { public static class Sized extends IntegerType { + private static final long serialVersionUID = 1L; public Sized() { this(4, 0); } public Sized(int size, long value) { super(size, value); } } @@ -16,8 +39,8 @@ class NTStruct extends Structure { public Sized field; @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "field" }); + protected List getFieldOrder() { + return Arrays.asList("field"); } } NTStruct s = new NTStruct(); @@ -27,8 +50,8 @@ class NTStruct extends Structure { public Sized field; @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "field" }); + protected List getFieldOrder() { + return Arrays.asList("field"); } } NTStruct s = new NTStruct(); @@ -78,6 +101,8 @@ public void testValueBoundaries() { class TestType extends IntegerType { + private static final long serialVersionUID = 1L; + public TestType(int size, long value) { super(size, value); } @@ -104,6 +129,8 @@ public void testUnsignedValues() { class TestType extends IntegerType { + private static final long serialVersionUID = 1L; + public TestType(int size, long value) { super(size, value); } @@ -116,6 +143,8 @@ assertEquals("Wrong unsigned int value", VALUE, new TestType(4, VALUE).longValue()); class UnsignedTestType extends IntegerType { + private static final long serialVersionUID = 1L; + public UnsignedTestType(int size, long value) { super(size, value, true); } diff -Nru libjna-java-4.2.2/test/com/sun/jna/JNALoadTest.java libjna-java-4.4.0/test/com/sun/jna/JNALoadTest.java --- libjna-java-4.2.2/test/com/sun/jna/JNALoadTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/JNALoadTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,18 +1,30 @@ /* Copyright (c) 2007-2009 Timothy Wall, 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.io.File; +import java.lang.ref.Reference; import java.lang.ref.WeakReference; import java.lang.reflect.Field; import java.net.MalformedURLException; @@ -26,11 +38,11 @@ * that no JNI classes are directly referenced in these tests. */ public class JNALoadTest extends TestCase implements Paths, GCWaits { - + private class TestLoader extends URLClassLoader { public TestLoader(boolean fromJar) throws MalformedURLException { super(new URL[] { - Platform.isWindowsCE() + Platform.isWindowsCE() ? new File("/Storage Card/" + (fromJar ? "jna.jar" : "test.jar")).toURI().toURL() : new File(BUILDDIR + (fromJar ? "/jna.jar" : "/classes")).toURI().toURL(), }, new CloverLoader()); @@ -41,12 +53,14 @@ assertLibraryExists(); } } - protected Class findClass(String name) throws ClassNotFoundException { + + @Override + protected Class findClass(String name) throws ClassNotFoundException { String boot = System.getProperty("jna.boot.library.path"); if (boot != null) { System.setProperty("jna.boot.library.path", ""); } - Class cls = super.findClass(name); + Class cls = super.findClass(name); if (boot != null) { System.setProperty("jna.boot.library.path", boot); } @@ -60,7 +74,7 @@ throw new Error("Expected JNA jar file at " + jar + " is missing"); } } - + protected void assertLibraryExists() { String osPrefix = Platform.getNativeLibraryResourcePrefix(); String name = System.mapLibraryName("jnidispatch").replace(".dylib", ".jnilib"); @@ -73,7 +87,7 @@ public void testAvoidJarUnpacking() throws Exception { System.setProperty("jna.nounpack", "true"); try { - Class cls = Class.forName("com.sun.jna.Native", true, new TestLoader(true)); + Class cls = Class.forName("com.sun.jna.Native", true, new TestLoader(true)); fail("Class com.sun.jna.Native should not be loadable if jna.nounpack=true: " + cls.getClassLoader()); @@ -88,7 +102,7 @@ public void testAvoidResourcePathLoading() throws Exception { System.setProperty("jna.noclasspath", "true"); try { - Class cls = Class.forName("com.sun.jna.Native", true, new TestLoader(false)); + Class cls = Class.forName("com.sun.jna.Native", true, new TestLoader(false)); fail("Class com.sun.jna.Native should not be loadable if jna.noclasspath=true: " + cls.getClassLoader()); @@ -102,7 +116,7 @@ public void testLoadAndUnloadFromJar() throws Exception { ClassLoader loader = new TestLoader(true); - Class cls = Class.forName("com.sun.jna.Native", true, loader); + Class cls = Class.forName("com.sun.jna.Native", true, loader); assertEquals("Wrong class loader", loader, cls.getClassLoader()); assertTrue("System property jna.loaded not set", Boolean.getBoolean("jna.loaded")); @@ -113,8 +127,8 @@ assertTrue("Native library not unpacked from jar: " + path, path.startsWith(System.getProperty("java.io.tmpdir"))); - WeakReference ref = new WeakReference(cls); - WeakReference clref = new WeakReference(loader); + Reference> ref = new WeakReference>(cls); + Reference clref = new WeakReference(loader); loader = null; cls = null; field = null; @@ -134,8 +148,8 @@ } if (f.exists()) { - assertTrue("Temporary jnidispatch not marked for later deletion: " - + f, new File(f.getAbsolutePath()+".x").exists()); + assertTrue("Temporary jnidispatch not marked for later deletion: " + f, + new File(f.getAbsolutePath()+".x").exists()); } assertFalse("System property jna.loaded not cleared", Boolean.getBoolean("jna.loaded")); @@ -144,11 +158,9 @@ try { loader = new TestLoader(true); cls = Class.forName("com.sun.jna.Native", true, loader); - } - catch(Throwable t) { + } catch(Throwable t) { fail("Couldn't load class again after discarding first load: " + t.getMessage()); - } - finally { + } finally { loader = null; cls = null; System.gc(); @@ -158,7 +170,7 @@ // GC Fails under OpenJDK(linux/ppc) public void testLoadAndUnloadFromResourcePath() throws Exception { ClassLoader loader = new TestLoader(false); - Class cls = Class.forName("com.sun.jna.Native", true, loader); + Class cls = Class.forName("com.sun.jna.Native", true, loader); assertEquals("Wrong class loader", loader, cls.getClassLoader()); assertTrue("System property jna.loaded not set", Boolean.getBoolean("jna.loaded")); @@ -167,8 +179,8 @@ String path = (String)field.get(null); assertNotNull("Native library not found", path); - WeakReference ref = new WeakReference(cls); - WeakReference clref = new WeakReference(loader); + Reference> ref = new WeakReference>(cls); + Reference clref = new WeakReference(loader); loader = null; cls = null; field = null; @@ -209,9 +221,18 @@ } } - // Fails on Sun JVM windows (32 and 64-bit) (JVM bug) - // Works with IBM J9 (jdk6) windows public void testLoadFromUnicodePath() throws Exception { + if (Platform.isWindows()) { + String vendor = System.getProperty("java.vendor"); + if (vendor != null) { + vendor = vendor.toLowerCase(); + if (vendor.contains("oracle") || vendor.contains("sun")) { + System.out.println("Skip " + getName() + " - Fails on Sun JVM windows (32 and 64-bit) (JVM bug), Works with IBM J9 (jdk6) windows"); + return; + } + } + } + final String UNICODE = getName() + "-\u0444\u043b\u0441\u0432\u0443"; File tmpdir = new File(System.getProperty("java.io.tmpdir")); File unicodeDir = new File(tmpdir, UNICODE); @@ -221,7 +242,7 @@ System.setProperty("jnidispatch.preserve", "true"); System.setProperty("jna.tmpdir", unicodeDir.getAbsolutePath()); ClassLoader loader = new TestLoader(true); - Class cls = Class.forName("com.sun.jna.Native", true, loader); + Class cls = Class.forName("com.sun.jna.Native", true, loader); assertEquals("Wrong class loader", loader, cls.getClassLoader()); assertTrue("System property jna.loaded not set", Boolean.getBoolean("jna.loaded")); diff -Nru libjna-java-4.2.2/test/com/sun/jna/LastErrorTest.java libjna-java-4.4.0/test/com/sun/jna/LastErrorTest.java --- libjna-java-4.2.2/test/com/sun/jna/LastErrorTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/LastErrorTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,39 +1,51 @@ /* Copyright (c) 2009 Timothy Wall, 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.Map; -import java.util.HashMap; -import java.util.Set; -import java.util.HashSet; import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; import junit.framework.TestCase; //@SuppressWarnings("unused") public class LastErrorTest extends TestCase { - - private static final Map OPTIONS = new HashMap() {{ - put(Library.OPTION_FUNCTION_MAPPER, new FunctionMapper() { - public String getFunctionName(NativeLibrary library, Method m) { - if (m.getName().equals("noThrowLastError") - || m.getName().equals("throwLastError")) { - return "setLastError"; + + private static final Map OPTIONS = + Collections.singletonMap(Library.OPTION_FUNCTION_MAPPER, new FunctionMapper() { + @Override + public String getFunctionName(NativeLibrary library, Method m) { + if (m.getName().equals("noThrowLastError") + || m.getName().equals("throwLastError")) { + return "setLastError"; + } + return m.getName(); } - return m.getName(); - } - }); - }}; + }); public interface TestLibrary extends Library { void setLastError(int code); @@ -42,8 +54,11 @@ } public static class DirectTestLibrary implements TestLibrary { + @Override public native void setLastError(int code); + @Override public native void noThrowLastError(int code); + @Override public native void throwLastError(int code) throws LastErrorException; static { Native.register(NativeLibrary.getInstance("testlib", OPTIONS)); @@ -51,16 +66,20 @@ } public void testLastErrorPerThreadStorage() throws Exception { - final TestLibrary lib = (TestLibrary)Native.loadLibrary("testlib", TestLibrary.class); + final TestLibrary lib = Native.loadLibrary("testlib", TestLibrary.class); final int NTHREADS = 100; final int[] errors = new int[NTHREADS]; - Set threads = new HashSet(); + List threads = new ArrayList(NTHREADS); for (int i=0;i < NTHREADS;i++) { final int idx = i; - Thread t = new Thread() { public void run() { - lib.setLastError(-idx-1); - errors[idx] = Native.getLastError(); - }}; + Thread t = new Thread("tLastErrorSetter-" + i) { + @Override + public void run() { + lib.setLastError(-idx-1); + errors[idx] = Native.getLastError(); + } + }; + t.setDaemon(true); // so we can stop the main thread if necessary threads.add(t); } int EXPECTED = 42; @@ -70,8 +89,10 @@ t.start(); } for (Thread t : threads) { - t.join(); + t.join(TimeUnit.SECONDS.toMillis(7L)); + assertFalse("Thread " + t.getName() + " still alive", t.isAlive()); } + assertEquals("Wrong error on main thread", EXPECTED, Native.getLastError()); for (int i=0;i < threads.size();i++) { assertEquals("Wrong error on thread " + i, -i-1, errors[i]); @@ -80,15 +101,14 @@ private final int ERROR = Platform.isWindows() ? 1 : -1; public void testThrowLastError() { - TestLibrary lib = (TestLibrary)Native.loadLibrary("testlib", TestLibrary.class, OPTIONS); + TestLibrary lib = Native.loadLibrary("testlib", TestLibrary.class, OPTIONS); lib.noThrowLastError(ERROR); assertEquals("Last error not preserved", ERROR, Native.getLastError()); try { lib.throwLastError(ERROR); fail("Method should throw LastErrorException"); - } - catch(LastErrorException e) { + } catch(LastErrorException e) { assertEquals("Exception should contain error code", ERROR, e.getErrorCode()); assertTrue("Exception should include error message: '" + e.getMessage() + "'", e.getMessage().length() > 0); } @@ -102,8 +122,7 @@ try { lib.throwLastError(ERROR); fail("Method should throw LastErrorException"); - } - catch(LastErrorException e) { + } catch(LastErrorException e) { assertEquals("Exception should contain error code", ERROR, e.getErrorCode()); assertTrue("Exception should include error message: " + e.getMessage(), e.getMessage().length() > 0); } diff -Nru libjna-java-4.2.2/test/com/sun/jna/LibraryLoadTest.java libjna-java-4.4.0/test/com/sun/jna/LibraryLoadTest.java --- libjna-java-4.2.2/test/com/sun/jna/LibraryLoadTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/LibraryLoadTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007-20013 Timothy Wall, 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * You can freely decide which license you want to apply to + * the project. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; @@ -27,7 +38,7 @@ import junit.framework.TestCase; public class LibraryLoadTest extends TestCase implements Paths { - + private class TestLoader extends URLClassLoader { public TestLoader(File path) throws MalformedURLException { super(new URL[] { path.toURI().toURL(), }, @@ -38,7 +49,7 @@ public void testLoadJNALibrary() { assertTrue("Pointer size should never be zero", Pointer.SIZE > 0); } - + public void testLoadJAWT() { if (!Platform.HAS_AWT || !Platform.HAS_JAWT) return; @@ -48,7 +59,7 @@ // AWT is unavailable AWT.loadJAWT(getName()); } - + public void testLoadAWTAfterJNA() { if (!Platform.HAS_AWT) return; @@ -58,7 +69,7 @@ Toolkit.getDefaultToolkit(); } } - + public void testExtractFromResourcePath() throws Exception { // doesn't actually load the resource assertNotNull(Native.extractFromResourcePath("testlib-path", new TestLoader(new File(TESTPATH)))); @@ -115,19 +126,19 @@ private Object load() { return Native.loadLibrary(Platform.C_LIBRARY_NAME, CLibrary.class); } - + public void testLoadProcess() { Native.loadLibrary(CLibrary.class); } - + public void testLoadProcessWithOptions() { Native.loadLibrary(CLibrary.class, Collections.EMPTY_MAP); } - + public void testLoadCLibrary() { load(); } - + private void copy(File src, File dst) throws Exception { FileInputStream is = new FileInputStream(src); FileOutputStream os = new FileOutputStream(dst); @@ -140,7 +151,7 @@ } finally { try { is.close(); } catch(IOException e) { } - try { os.close(); } catch(IOException e) { } + try { os.close(); } catch(IOException e) { } } } @@ -163,7 +174,7 @@ fail("Library '" + newLibName + "' at " + dst + " could not be loaded: " + e); } } - + public void testLoadLibraryWithLongName() throws Exception { File tmpdir = Native.getTempDir(); String libName = NativeLibrary.mapSharedLibraryName("testlib"); @@ -202,7 +213,7 @@ } } } - + public void testLoadFrameworkLibraryAbsolute() { if (Platform.isMac()) { final String PATH = "/System/Library/Frameworks/CoreServices"; @@ -255,7 +266,7 @@ // dependent libraries in the same directory as the original public void testLoadDependentLibraryWithAlteredSearchPath() { try { - TestLib2 lib = (TestLib2)Native.loadLibrary("testlib2", TestLib2.class); + TestLib2 lib = Native.loadLibrary("testlib2", TestLib2.class); lib.dependentReturnFalse(); } catch(UnsatisfiedLinkError e) { @@ -271,11 +282,11 @@ public void testLoadProperCLibraryVersion() { if (Platform.isWindows()) return; - CLibrary lib = (CLibrary)Native.loadLibrary("c", CLibrary.class); + CLibrary lib = Native.loadLibrary("c", CLibrary.class); assertNotNull("Couldn't get current user", lib.getpwuid(lib.geteuid())); } - + private static class AWT { public static void loadJAWT(String name) { Frame f = new Frame(name); diff -Nru libjna-java-4.2.2/test/com/sun/jna/MemoryTest.java libjna-java-4.4.0/test/com/sun/jna/MemoryTest.java --- libjna-java-4.2.2/test/com/sun/jna/MemoryTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/MemoryTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,20 +1,33 @@ /* Copyright (c) 2007 Timothy Wall, 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.lang.ref.Reference; import java.lang.ref.WeakReference; -import java.nio.Buffer; +import java.lang.reflect.Field; import java.nio.ByteBuffer; +import java.util.Map; import junit.framework.TestCase; @@ -23,23 +36,24 @@ public void testAutoFreeMemory() throws Exception { final boolean[] flag = { false }; Memory core = new Memory(10) { + @Override protected void finalize() { super.finalize(); flag[0] = true; } }; Pointer shared = core.share(0, 5); - WeakReference ref = new WeakReference(core); - + Reference ref = new WeakReference(core); + core = null; System.gc(); - long start = System.currentTimeMillis(); assertFalse("Memory prematurely GC'd", flag[0]); assertNotNull("Base memory GC'd while shared memory extant", ref.get()); // Avoid having IBM J9 prematurely nullify "shared" shared.setInt(0, 0); shared = null; + long start = System.currentTimeMillis(); System.gc(); Memory.purge(); for (int i=0;i < GC_WAITS && ref.get() != null;i++) { @@ -47,7 +61,8 @@ System.gc(); Memory.purge(); } - assertNull("Memory not GC'd", ref.get()); + long end = System.currentTimeMillis(); + assertNull("Memory not GC'd after " + (end - start) + " millis", ref.get()); } public void testShareMemory() { @@ -122,8 +137,8 @@ m.clear(); ByteBuffer b = m.getByteBuffer(0, m.size()); - WeakReference ref = new WeakReference(m); - WeakReference 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); @@ -138,7 +153,7 @@ System.gc(); Memory.purge(); } - assertNotNull("Memory GC'd while NIO Buffer still extant", ref.get()); + assertNotNull("Memory GC'd while NIO Buffer still exists", ref.get()); // Avoid IBM J9 optimization resulting in premature GC of buffer b.put((byte)0); @@ -155,6 +170,44 @@ assertNull("Memory not GC'd after buffer GC'd\n", ref.get()); } + public void testDump() { + // test with 15 bytes so last line has less than 4 bytes + int n = 15; + + Memory m = new Memory(n); + + for (int i = 0; i < n; i++) { + m.setByte(i, (byte) i); + } + + String ls = System.getProperty("line.separator"); + + assertEquals("memory dump" + ls + + "[00010203]" + ls + + "[04050607]" + ls + + "[08090a0b]" + ls + + "[0c0d0e]" + ls, m.dump()); + } + + public void testRemoveAllocatedMemoryMap() throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException { + // Make sure there are no remaining allocations + Memory.disposeAll(); + + // get a reference to the allocated memory + Field allocatedMemoryField = Memory.class.getDeclaredField("allocatedMemory"); + allocatedMemoryField.setAccessible(true); + Map> allocatedMemory = (Map>) allocatedMemoryField.get(null); + assertEquals(0, allocatedMemory.size()); + + // Test allocation and ensure it is accounted for + Memory mem = new Memory(1024); + assertEquals(1, allocatedMemory.size()); + + // Dispose memory and ensure allocation is removed from allocatedMemory-Map + mem.dispose(); + assertEquals(0, allocatedMemory.size()); + } + public static void main(String[] args) { junit.textui.TestRunner.run(MemoryTest.class); } diff -Nru libjna-java-4.2.2/test/com/sun/jna/NativeLibraryTest.java libjna-java-4.4.0/test/com/sun/jna/NativeLibraryTest.java --- libjna-java-4.2.2/test/com/sun/jna/NativeLibraryTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/NativeLibraryTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,33 +1,43 @@ /* Copyright (c) 2007 Timothy Wall, 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * You can freely decide which license you want to apply to + * the project. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.io.ByteArrayInputStream; import java.io.File; import java.io.InputStream; +import java.lang.ref.Reference; import java.lang.ref.WeakReference; import java.net.MalformedURLException; import java.net.URL; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.Collections; + import com.sun.jna.win32.W32APIOptions; import junit.framework.TestCase; public class NativeLibraryTest extends TestCase { - + public static interface TestLibrary extends Library { int callCount(); } @@ -59,13 +69,13 @@ public void testGCNativeLibrary() throws Exception { NativeLibrary lib = NativeLibrary.getInstance("testlib"); - WeakReference ref = new WeakReference(lib); + Reference ref = new WeakReference(lib); lib = null; System.gc(); long start = System.currentTimeMillis(); while (ref.get() != null) { Thread.sleep(10); - if (System.currentTimeMillis() - start > 5000) + if ((System.currentTimeMillis() - start) > 5000L) break; } assertNull("Library not GC'd", ref.get()); @@ -77,56 +87,57 @@ // occasionally get the same library handle back on subsequent dlopen Thread.sleep(2); - TestLibrary lib = (TestLibrary)Native.loadLibrary("testlib", TestLibrary.class); + TestLibrary lib = Native.loadLibrary("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"); } } - + public void testUseSingleLibraryInstance() { - TestLibrary lib = (TestLibrary)Native.loadLibrary("testlib", TestLibrary.class); + TestLibrary lib = Native.loadLibrary("testlib", TestLibrary.class); int count = lib.callCount(); - TestLibrary lib2 = (TestLibrary)Native.loadLibrary("testlib", TestLibrary.class); + TestLibrary lib2 = Native.loadLibrary("testlib", TestLibrary.class); int count2 = lib2.callCount(); assertEquals("Interfaces should share a library instance", count + 1, count2); } public void testAliasLibraryFilename() { - TestLibrary lib = (TestLibrary)Native.loadLibrary("testlib", TestLibrary.class); + TestLibrary lib = Native.loadLibrary("testlib", TestLibrary.class); int count = lib.callCount(); NativeLibrary nl = NativeLibrary.getInstance("testlib"); - TestLibrary lib2 = (TestLibrary)Native.loadLibrary(nl.getFile().getName(), TestLibrary.class); + TestLibrary lib2 = Native.loadLibrary(nl.getFile().getName(), TestLibrary.class); int count2 = lib2.callCount(); assertEquals("Simple filename load not aliased", count + 1, count2); } - + public void testAliasLibraryFullPath() { - TestLibrary lib = (TestLibrary)Native.loadLibrary("testlib", TestLibrary.class); + TestLibrary lib = Native.loadLibrary("testlib", TestLibrary.class); int count = lib.callCount(); NativeLibrary nl = NativeLibrary.getInstance("testlib"); - TestLibrary lib2 = (TestLibrary)Native.loadLibrary(nl.getFile().getAbsolutePath(), TestLibrary.class); + TestLibrary lib2 = Native.loadLibrary(nl.getFile().getAbsolutePath(), TestLibrary.class); int count2 = lib2.callCount(); assertEquals("Full pathname load not aliased", count + 1, count2); } - + public void testAliasSimpleLibraryName() throws Exception { NativeLibrary nl = NativeLibrary.getInstance("testlib"); File file = nl.getFile(); - WeakReference ref = new WeakReference(nl); + Reference ref = new WeakReference(nl); nl = null; System.gc(); long start = System.currentTimeMillis(); while (ref.get() != null) { Thread.sleep(10); - if (System.currentTimeMillis() - start > 5000) + if ((System.currentTimeMillis() - start) > 5000L) { fail("Timed out waiting for library to be GC'd"); + } } - TestLibrary lib = (TestLibrary)Native.loadLibrary(file.getAbsolutePath(), TestLibrary.class); + TestLibrary lib = Native.loadLibrary(file.getAbsolutePath(), TestLibrary.class); int count = lib.callCount(); - TestLibrary lib2 = (TestLibrary)Native.loadLibrary("testlib", TestLibrary.class); + TestLibrary lib2 = Native.loadLibrary("testlib", TestLibrary.class); int count2 = lib2.callCount(); assertEquals("Simple library name not aliased", count + 1, count2); } @@ -135,9 +146,9 @@ NativeLibrary lib = NativeLibrary.getInstance("testlib"); try { Function f = lib.getFunction(null); - fail("Function must have a name"); - } - catch(NullPointerException e) { + fail("Function must have a name: " + f); + } catch(NullPointerException e) { + // expected } } @@ -154,35 +165,34 @@ public void testFunctionHoldsLibraryReference() throws Exception { NativeLibrary lib = NativeLibrary.getInstance("testlib"); - WeakReference ref = new WeakReference(lib); + Reference ref = new WeakReference(lib); Function f = lib.getFunction("callCount"); lib = null; System.gc(); - long start = System.currentTimeMillis(); - while (ref.get() != null && System.currentTimeMillis() - start < 2000) { - Thread.sleep(10); + for (long start = System.currentTimeMillis(); (ref.get() != null) && ((System.currentTimeMillis() - start) < 2000L); ) { + Thread.sleep(10); } assertNotNull("Library GC'd when it should not be", ref.get()); f.invokeInt(new Object[0]); f = null; System.gc(); - while (ref.get() != null && System.currentTimeMillis() - start < 5000) { - Thread.sleep(10); + for (long start = System.currentTimeMillis(); (ref.get() != null) && ((System.currentTimeMillis() - start) < 5000L); ) { + Thread.sleep(10); } assertNull("Library not GC'd", ref.get()); } - + public void testLookupGlobalVariable() { NativeLibrary lib = NativeLibrary.getInstance("testlib"); Pointer global = lib.getGlobalVariableAddress("test_global"); assertNotNull("Test variable not found", global); final int MAGIC = 0x12345678; assertEquals("Wrong value for library global variable", MAGIC, global.getInt(0)); - + global.setInt(0, MAGIC+1); assertEquals("Library global variable not updated", MAGIC+1, global.getInt(0)); } - + public void testMatchUnversionedToVersioned() throws Exception { File lib0 = File.createTempFile("lib", ".so.0"); File dir = lib0.getParentFile(); @@ -195,12 +205,11 @@ File lib1_1 = new File(dir, "lib" + name + ".so.1.1"); lib1_1.createNewFile(); lib1_1.deleteOnExit(); - List path = Arrays.asList(new String[] { dir.getCanonicalPath() }); - assertEquals("Latest versioned library not found when unversioned requested", + assertEquals("Latest versioned library not found when unversioned requested for path=" + dir, lib1_1.getCanonicalPath(), - NativeLibrary.matchLibrary(name, path)); + NativeLibrary.matchLibrary(name, Collections.singletonList(dir.getCanonicalPath()))); } - + public void testAvoidFalseMatch() throws Exception { File lib0 = File.createTempFile("lib", ".so.1"); File dir = lib0.getParentFile(); @@ -210,10 +219,9 @@ File lib1 = new File(dir, "lib" + name + "-client.so.2"); lib1.createNewFile(); lib1.deleteOnExit(); - List path = Arrays.asList(new String[] { dir.getCanonicalPath() }); - assertEquals("Library with similar prefix should be ignored", + assertEquals("Library with similar prefix should be ignored for path=" + dir, lib0.getCanonicalPath(), - NativeLibrary.matchLibrary(name, path)); + NativeLibrary.matchLibrary(name, Collections.singletonList(dir.getCanonicalPath()))); } public void testParseVersion() throws Exception { @@ -230,7 +238,7 @@ assertEquals("Badly parsed version", EXPECTED[i], NativeLibrary.parseVersion(VERSIONS[i]), 0.0000001); } } - + // XFAIL on android public void testGetProcess() { if (Platform.isAndroid()) { @@ -264,9 +272,7 @@ } public void testLoadLibraryWithOptions() { - Map options = new HashMap(); - options.put(Library.OPTION_OPEN_FLAGS, new Integer(-1)); - Native.loadLibrary("testlib", TestLibrary.class, options); + Native.loadLibrary("testlib", TestLibrary.class, Collections.singletonMap(Library.OPTION_OPEN_FLAGS, Integer.valueOf(-1))); } public interface Kernel32 { @@ -277,23 +283,21 @@ if (!Platform.isWindows()) { return; } - NativeLibrary kernel32 = (NativeLibrary)NativeLibrary.getInstance("kernel32", W32APIOptions.DEFAULT_OPTIONS); + NativeLibrary kernel32 = NativeLibrary.getInstance("kernel32", W32APIOptions.DEFAULT_OPTIONS); Function get = kernel32.getFunction("GetLastError"); Function set = kernel32.getFunction("SetLastError"); - assertEquals("SetLastError should not be customized", Function.class, set.getClass()); + assertEquals("SetLastError should not be customized", Function.class, set.getClass()); assertTrue("GetLastError should be a Function", Function.class.isAssignableFrom(get.getClass())); assertTrue("GetLastError should be a customized Function", get.getClass() != Function.class); final int EXPECTED = 42; - set.invokeVoid(new Object[] { new Integer(EXPECTED) }); + set.invokeVoid(new Object[] { Integer.valueOf(EXPECTED) }); assertEquals("Wrong error", EXPECTED, get.invokeInt(null)); } public void testCleanupOnLoadError() throws Exception { - Map options = new HashMap(); - options.put(Library.OPTION_CLASSLOADER, new DisfunctClassLoader()); int previousTempFileCount = Native.getTempDir().listFiles().length; try { - NativeLibrary.getInstance("disfunct", options); + NativeLibrary.getInstance("disfunct", Collections.singletonMap(Library.OPTION_CLASSLOADER, new DisfunctClassLoader())); fail("Expected NativeLibrary.getInstance() to fail with an UnsatisfiedLinkError here."); } catch(UnsatisfiedLinkError e) { int currentTempFileCount = Native.getTempDir().listFiles().length; @@ -303,6 +307,7 @@ // returns unloadable "shared library" on any input private class DisfunctClassLoader extends ClassLoader { + @Override public URL getResource(String name) { try { return new URL("jar", "", name); @@ -312,6 +317,7 @@ } } + @Override public InputStream getResourceAsStream(String name) { return new ByteArrayInputStream(new byte[0]); } diff -Nru libjna-java-4.2.2/test/com/sun/jna/NativeTest.java libjna-java-4.4.0/test/com/sun/jna/NativeTest.java --- libjna-java-4.2.2/test/com/sun/jna/NativeTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/NativeTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,18 +1,31 @@ /* Copyright (c) 2007-2013 Timothy Wall, 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * You can freely decide which license you want to apply to + * the project. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.io.File; +import java.lang.reflect.Method; +import java.nio.charset.Charset; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; @@ -24,9 +37,39 @@ //@SuppressWarnings("unused") public class NativeTest extends TestCase { - + private static final String UNICODE = "[\u0444]"; + public void testLoadLibraryMethods() throws Exception { + Class[][] params = { + { Class.class }, + { Class.class, Map.class }, + { String.class, Class.class }, + { String.class, Class.class, Map.class } + }; + + StringBuilder signature = new StringBuilder(Long.SIZE); + for (Class[] paramTypes : params) { + signature.setLength(0); + signature.append('('); + for (Class p : paramTypes) { + signature.append(Native.getSignature(p)); + } + signature.append(')'); + + try { + Method m = Native.class.getMethod("loadLibrary", paramTypes); + Class returnType = m.getReturnType(); + signature.append(Native.getSignature(returnType)); + assertSame("Mismatched return type for signature=" + signature, Object.class, returnType); +// System.out.println("===>" + m.getName() + ": " + signature); + } catch(NoSuchMethodError err) { + fail("No method for signature=" + signature); + } + } + } + + @SuppressWarnings("deprecation") public void testVersion() { String[] INPUTS = { "1.0", "1.0.1", "2.1.3" }; float[] EXPECTED = { 1.0f, 1.0f, 2.1f }; @@ -55,9 +98,9 @@ // 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"; - + if (!UNICODE.equals(new String(UNICODE.getBytes()))) { - // If the extended characters aren't encodable in the default + // If the extended characters aren't encodable in the default // encoding, punt and use straight ASCII UNICODE = ""; for (char ch=1;ch < 128;ch++) { @@ -65,23 +108,23 @@ } } final String UNICODEZ = UNICODE + "\0more stuff"; - + byte[] customEncoded = Native.getBytes(UNICODE, ENCODING); byte[] expected = UNICODE.getBytes(ENCODING); for (int i=0;i < Math.min(customEncoded.length, expected.length);i++) { - assertEquals("Improperly encoded (" + ENCODING + ") from Java at " + i, + assertEquals("Improperly encoded (" + ENCODING + ") from Java at " + i, expected[i], customEncoded[i]); } - assertEquals("Wrong number of encoded characters (" + ENCODING + ")", + assertEquals("Wrong number of encoded characters (" + ENCODING + ")", expected.length, customEncoded.length); String result = Native.toString(customEncoded, ENCODING); - assertEquals("Improperly decoded from native bytes (" + ENCODING + ")", + assertEquals("Improperly decoded from native bytes (" + ENCODING + ")", UNICODE, result); - + assertEquals("Should truncate bytes at NUL terminator", UNICODE, Native.toString(UNICODEZ.getBytes(ENCODING), ENCODING)); } - + public void testToStringList() { List expected = Arrays.asList(getClass().getPackage().getName(), getClass().getSimpleName(), "testToStringList"); StringBuilder sb = new StringBuilder(); @@ -89,7 +132,7 @@ sb.append(value).append('\0'); } sb.append('\0'); - + List actual = Native.toStringList(sb.toString().toCharArray()); assertEquals("Mismatched result size", expected.size(), actual.size()); for (int index = 0; index < expected.size(); index++) { @@ -102,32 +145,50 @@ public void testDefaultStringEncoding() throws Exception { final String UNICODE = "\u0444\u043b\u0441\u0432\u0443"; final String UNICODEZ = UNICODE + "\0more stuff"; - byte[] utf8 = Native.getBytes(UNICODE); + byte[] nativeEnc = Native.getBytes(UNICODE); byte[] expected = UNICODE.getBytes(Native.DEFAULT_ENCODING); - for (int i=0;i < Math.min(utf8.length, expected.length);i++) { - assertEquals("Improperly encoded at " + i, - expected[i], utf8[i]); - } - assertEquals("Wrong number of encoded characters", expected.length, utf8.length); - String result = Native.toString(utf8); - assertEquals("Improperly decoded", UNICODE, result); - + for (int i=0;i < Math.min(nativeEnc.length, expected.length);i++) { + assertEquals("Improperly encoded at " + i, + expected[i], nativeEnc[i]); + } + assertEquals("Wrong number of encoded characters", expected.length, nativeEnc.length); + String result = Native.toString(nativeEnc); + // The native encoding might not support our test string; the result + // will then be all '?' + if (!result.matches("^\\?+$")) { + assertEquals("Improperly decoded", UNICODE, result); + } + // When the native encoding doesn't support our test string, we can only + // usefully compare the lengths. assertEquals("Should truncate bytes at NUL terminator", - UNICODE, Native.toString(UNICODEZ.getBytes(Native.DEFAULT_ENCODING))); + UNICODE.length(), Native.toString(UNICODEZ.getBytes(Native.DEFAULT_ENCODING)).length()); } - + public void testCustomizeDefaultStringEncoding() { Properties oldprops = (Properties)System.getProperties().clone(); - final String ENCODING = System.getProperty("file.encoding"); + String encoding = null; + // Choose a charset that is not the default encoding so we can actually + // tell we changed it. + for (String charset : Charset.availableCharsets().keySet()) { + if (!charset.equals(Native.DEFAULT_ENCODING)) { + encoding = charset; + break; + } + } + assertNotNull("No available encodings other than the default!?", encoding); try { - System.setProperty("jna.encoding", ENCODING); - assertEquals("Default encoding should match jna.encoding setting", ENCODING, Native.getDefaultStringEncoding()); + System.setProperty("jna.encoding", encoding); + assertEquals("Default encoding should match jna.encoding setting", encoding, Native.getDefaultStringEncoding()); } finally { System.setProperties(oldprops); } } + public void testSizeof() { + assertEquals("Wrong bool size", 1, Native.BOOL_SIZE); + } + public static interface TestLib extends Library { interface VoidCallback extends Callback { void callback(); @@ -137,14 +198,16 @@ public void testSynchronizedAccess() throws Exception { final boolean[] lockHeld = { false }; final NativeLibrary nlib = NativeLibrary.getInstance("testlib", TestLib.class.getClassLoader()); - final TestLib lib = (TestLib)Native.loadLibrary("testlib", TestLib.class); - final TestLib synchlib = (TestLib)Native.synchronizedLibrary(lib); + final TestLib lib = Native.loadLibrary("testlib", TestLib.class); + final TestLib synchlib = (TestLib)Native.synchronizedLibrary(lib); final TestLib.VoidCallback cb = new TestLib.VoidCallback() { + @Override public void callback() { lockHeld[0] = Thread.holdsLock(nlib); } }; Thread t0 = new Thread() { + @Override public void run() { lib.callVoidCallback(cb); } @@ -155,6 +218,7 @@ lockHeld[0]); Thread t1 = new Thread() { + @Override public void run() { synchlib.callVoidCallback(cb); } @@ -169,17 +233,18 @@ static class InnerTestClass extends Structure { interface TestCallback extends Callback { } static class InnerSubclass extends InnerTestClass implements Structure.ByReference { } - protected List getFieldOrder() { - return Collections.EMPTY_LIST; + @Override + protected List getFieldOrder() { + return Collections.emptyList(); } } } - + public void testFindInterfaceClass() throws Exception { - Class interfaceClass = TestInterface.class; - Class cls = TestInterface.InnerTestClass.class; - Class subClass = TestInterface.InnerTestClass.InnerSubclass.class; - Class callbackClass = TestInterface.InnerTestClass.TestCallback.class; + Class interfaceClass = TestInterface.class; + Class cls = TestInterface.InnerTestClass.class; + Class subClass = TestInterface.InnerTestClass.InnerSubclass.class; + Class callbackClass = TestInterface.InnerTestClass.TestCallback.class; assertEquals("Enclosing interface not found for class", interfaceClass, Native.findEnclosingLibraryClass(cls)); assertEquals("Enclosing interface not found for derived class", @@ -192,62 +257,56 @@ int TEST_ALIGNMENT = Structure.ALIGN_NONE; TypeMapper TEST_MAPPER = new DefaultTypeMapper(); String TEST_ENCODING = "test-encoding"; - Map TEST_OPTS = new HashMap() { { - put(OPTION_CLASSLOADER, TestInterfaceWithInstance.class.getClassLoader()); - put(OPTION_TYPE_MAPPER, TEST_MAPPER); - put(OPTION_STRUCTURE_ALIGNMENT, new Integer(TEST_ALIGNMENT)); - put(OPTION_STRING_ENCODING, TEST_ENCODING); - }}; - TestInterfaceWithInstance ARBITRARY = (TestInterfaceWithInstance) - Native.loadLibrary("testlib", TestInterfaceWithInstance.class, TEST_OPTS); + Map TEST_OPTS = new HashMap() { + private static final long serialVersionUID = 1L; // we're not serializing it + + { + put(OPTION_CLASSLOADER, TestInterfaceWithInstance.class.getClassLoader()); + put(OPTION_TYPE_MAPPER, TEST_MAPPER); + put(OPTION_STRUCTURE_ALIGNMENT, Integer.valueOf(TEST_ALIGNMENT)); + put(OPTION_STRING_ENCODING, TEST_ENCODING); + } + }; + TestInterfaceWithInstance ARBITRARY = Native.loadLibrary("testlib", TestInterfaceWithInstance.class, TEST_OPTS); abstract class TestStructure extends Structure {} } public void testOptionsInferenceFromInstanceField() { - Class[] classes = { TestInterfaceWithInstance.class, TestInterfaceWithInstance.TestStructure.class }; + Class[] classes = { TestInterfaceWithInstance.class, TestInterfaceWithInstance.TestStructure.class }; String[] desc = { "interface", "structure from interface" }; for (int i=0;i < classes.length;i++) { - assertEquals("Wrong options found for " + desc[i] - + " which provides an instance", - TestInterfaceWithInstance.TEST_OPTS, - Native.getLibraryOptions(classes[i])); - assertEquals("Wrong type mapper found for " + desc[i], + assertEquals("Wrong type mapper found for " + desc[i], TestInterfaceWithInstance.TEST_MAPPER, Native.getTypeMapper(classes[i])); - assertEquals("Wrong alignment found for " + desc[i], + assertEquals("Wrong alignment found for " + desc[i], TestInterfaceWithInstance.TEST_ALIGNMENT, Native.getStructureAlignment(classes[i])); - assertEquals("Wrong string encoding found for " + desc[i], + assertEquals("Wrong string encoding found for " + desc[i], TestInterfaceWithInstance.TEST_ENCODING, Native.getStringEncoding(classes[i])); } } - + public interface TestInterfaceWithOptions extends Library { int TEST_ALIGNMENT = Structure.ALIGN_NONE; TypeMapper TEST_MAPPER = new DefaultTypeMapper(); String TEST_ENCODING = "test-encoding"; - Map OPTIONS = new HashMap() { { - put(OPTION_TYPE_MAPPER, TEST_MAPPER); - put(OPTION_STRUCTURE_ALIGNMENT, new Integer(TEST_ALIGNMENT)); - put(OPTION_STRING_ENCODING, TEST_ENCODING); - }}; + Map OPTIONS = new HashMap() { + private static final long serialVersionUID = 1L; // we're not serializing it + + { + put(OPTION_TYPE_MAPPER, TEST_MAPPER); + put(OPTION_STRUCTURE_ALIGNMENT, Integer.valueOf(TEST_ALIGNMENT)); + put(OPTION_STRING_ENCODING, TEST_ENCODING); + } + }; abstract class TestStructure extends Structure {} } public void testOptionsInferenceFromOptionsField() { - Class[] classes = { TestInterfaceWithOptions.class, TestInterfaceWithOptions.TestStructure.class }; - for (int i=0;i < classes.length;i++) { - assertEquals("Wrong options found for interface which provides OPTIONS", - TestInterfaceWithOptions.OPTIONS, - Native.getLibraryOptions(classes[i])); - assertEquals("Wrong type mapper found", - TestInterfaceWithOptions.TEST_MAPPER, - Native.getTypeMapper(classes[i])); - assertEquals("Wrong alignment found", - TestInterfaceWithOptions.TEST_ALIGNMENT, - Native.getStructureAlignment(classes[i])); - assertEquals("Wrong encoding found", - TestInterfaceWithOptions.TEST_ENCODING, - Native.getStringEncoding(classes[i])); + Class[] classes = { TestInterfaceWithOptions.class, TestInterfaceWithOptions.TestStructure.class }; + for (Class cls : classes) { + assertEquals("Wrong type mapper found", TestInterfaceWithOptions.TEST_MAPPER, Native.getTypeMapper(cls)); + assertEquals("Wrong alignment found", TestInterfaceWithOptions.TEST_ALIGNMENT, Native.getStructureAlignment(cls)); + assertEquals("Wrong encoding found", TestInterfaceWithOptions.TEST_ENCODING, Native.getStringEncoding(cls)); } } @@ -257,10 +316,10 @@ abstract class TestStructure extends Structure { } } public void testOptionsInferenceFromTypeMapperField() { - assertEquals("Wrong type mapper found for interface which provides TYPE_MAPPER", + assertEquals("Wrong type mapper found for interface which provides TYPE_MAPPER", TestInterfaceWithTypeMapper.TEST_MAPPER, Native.getTypeMapper(TestInterfaceWithTypeMapper.class)); - assertEquals("Wrong type mapper found for structure from interface which provides TYPE_MAPPER", + assertEquals("Wrong type mapper found for structure from interface which provides TYPE_MAPPER", TestInterfaceWithTypeMapper.TEST_MAPPER, Native.getTypeMapper(TestInterfaceWithTypeMapper.TestStructure.class)); } @@ -270,10 +329,10 @@ abstract class TestStructure extends Structure { } } public void testOptionsInferenceFromAlignmentField() { - assertEquals("Wrong alignment found for interface which provides STRUCTURE_ALIGNMENT", + assertEquals("Wrong alignment found for interface which provides STRUCTURE_ALIGNMENT", Structure.ALIGN_NONE, Native.getStructureAlignment(TestInterfaceWithAlignment.class)); - assertEquals("Wrong alignment found for structure from interface which provides STRUCTURE_ALIGNMENT", + assertEquals("Wrong alignment found for structure from interface which provides STRUCTURE_ALIGNMENT", Structure.ALIGN_NONE, Native.getStructureAlignment(TestInterfaceWithAlignment.TestStructure.class)); } @@ -283,14 +342,37 @@ abstract class TestStructure extends Structure { } } public void testOptionsInferenceFromEncodingField() { - assertEquals("Wrong encoding found for interface which provides STRING_ENCODING", + assertEquals("Wrong encoding found for interface which provides STRING_ENCODING", TestInterfaceWithEncoding.STRING_ENCODING, Native.getStringEncoding(TestInterfaceWithEncoding.class)); - assertEquals("Wrong encoding found for structure from interface which provides STRING_ENCODING", + assertEquals("Wrong encoding found for structure from interface which provides STRING_ENCODING", TestInterfaceWithEncoding.STRING_ENCODING, Native.getStringEncoding(TestInterfaceWithEncoding.TestStructure.class)); } + public interface OptionsBase extends Library { + int STRUCTURE_ALIGNMENT = Structure.ALIGN_NONE; + TypeMapper TYPE_MAPPER = new DefaultTypeMapper(); + class TypeMappedStructure extends Structure { + public String stringField; + @Override + protected List getFieldOrder() { + return Arrays.asList("stringField"); + } + } + } + public interface OptionsSubclass extends OptionsBase, Library { + TypeMapper _MAPPER = new DefaultTypeMapper(); + Map _OPTIONS = Collections.singletonMap(Library.OPTION_TYPE_MAPPER, _MAPPER); + OptionsSubclass INSTANCE = Native.loadLibrary("testlib", OptionsSubclass.class, _OPTIONS); + } + public void testStructureOptionsInference() { + Structure s = new OptionsBase.TypeMappedStructure(); + assertEquals("Wrong structure alignment for base structure", + Structure.ALIGN_NONE, Native.getStructureAlignment(s.getClass())); + assertEquals("Wrong type mapper for base structure", OptionsBase.TYPE_MAPPER, s.getTypeMapper()); + } + public void testCharArrayToString() { char[] buf = { 'a', 'b', 'c', '\0', 'd', 'e' }; assertEquals("Wrong String generated", "abc", Native.toString(buf)); @@ -409,18 +491,18 @@ "com.sun.jna.NativeLibraryTest", "com.sun.jna.PointerTest", "com.sun.jna.MemoryTest", - "com.sun.jna.LibraryLoadTest", + "com.sun.jna.LibraryLoadTest", "com.sun.jna.ArgumentsMarshalTest", "com.sun.jna.ReturnTypesTest", - "com.sun.jna.TypeMapperTest", + "com.sun.jna.TypeMapperTest", "com.sun.jna.ByReferenceArgumentsTest", - "com.sun.jna.LastErrorTest", + "com.sun.jna.LastErrorTest", "com.sun.jna.StructureTest",// 1 wce failure (RO fields) "com.sun.jna.StructureByValueTest", "com.sun.jna.UnionTest", - "com.sun.jna.IntegerTypeTest", + "com.sun.jna.IntegerTypeTest", "com.sun.jna.VMCrashProtectionTest", - "com.sun.jna.CallbacksTest", + "com.sun.jna.CallbacksTest", "com.sun.jna.JNAUnloadTest", "com.sun.jna.DirectTest", "com.sun.jna.DirectArgumentsMarshalTest", @@ -436,12 +518,20 @@ System.out.println("Running tests on class " + args[i]); try { junit.textui.TestRunner.run((Class) Class.forName(args[i])); - } - catch(Throwable e) { + } catch(Throwable e) { e.printStackTrace(); } } try { Thread.sleep(300000); } catch(Exception e) { } } } + + public void testVersionComparison() { + assertTrue("Equal version", Native.isCompatibleVersion("5.1.0", "5.1.0")); + assertTrue("New revision", Native.isCompatibleVersion("5.2.0", "5.2.1")); + assertTrue("New minor provided, older minor expected", Native.isCompatibleVersion("5.1.0", "5.10.0")); + assertFalse("Old minor provided, new minor expected", Native.isCompatibleVersion("5.10.0", "5.1.0")); + assertFalse("Different major (expected < provided)", Native.isCompatibleVersion("4.0.0", "5.0.0")); + assertFalse("Different major (expected > provided)", Native.isCompatibleVersion("5.0.0", "4.0.0")); + } } diff -Nru libjna-java-4.2.2/test/com/sun/jna/Paths.java libjna-java-4.4.0/test/com/sun/jna/Paths.java --- libjna-java-4.2.2/test/com/sun/jna/Paths.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/Paths.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2013 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

        - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; diff -Nru libjna-java-4.2.2/test/com/sun/jna/PerformanceTest.java libjna-java-4.4.0/test/com/sun/jna/PerformanceTest.java --- libjna-java-4.2.2/test/com/sun/jna/PerformanceTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/PerformanceTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,28 +1,36 @@ /* Copyright (c) 2009-2015 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

        - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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 junit.framework.*; -import com.sun.jna.*; -import com.sun.jna.ptr.PointerByReference; -import java.lang.ref.*; import java.io.File; import java.nio.Buffer; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.Map; -import java.util.HashMap; -import java.lang.reflect.Method; +import java.util.Collections; +import java.lang.reflect.Method; import com.sun.jna.DirectTest.TestInterface; import com.sun.jna.DirectTest.TestLibrary; @@ -40,7 +48,7 @@ } System.load(path); } - + private static native double cos(double x); private static native int getpid(); } @@ -52,7 +60,7 @@ static class MathLibrary { public static native double cos(double x); - + static { Native.register(Platform.MATH_LIBRARY_NAME); } @@ -64,6 +72,8 @@ static class CLibrary { public static class size_t extends IntegerType { + private static final long serialVersionUID = 1L; + public size_t() { super(Native.POINTER_SIZE); } @@ -81,7 +91,7 @@ public static native int strlen(Pointer p); public static native int strlen(byte[] b); public static native int strlen(Buffer b); - + static { Native.register(Platform.C_LIBRARY_NAME); } @@ -120,13 +130,12 @@ Pointer pb = Native.getDirectBufferPointer(b); String mname = Platform.MATH_LIBRARY_NAME; - MathInterface mlib = (MathInterface) - Native.loadLibrary(mname, MathInterface.class); + MathInterface mlib = Native.loadLibrary(mname, MathInterface.class); Function f = NativeLibrary.getInstance(mname).getFunction("cos"); /////////////////////////////////////////// // cos - Object[] args = { new Double(0) }; + Object[] args = { Double.valueOf(0) }; double dresult; long start = System.currentTimeMillis(); for (int i=0;i < COUNT;i++) { @@ -199,22 +208,21 @@ delta = System.currentTimeMillis() - start; System.out.println("cos (pure java): " + delta + "ms"); - Pointer presult; String cname = Platform.C_LIBRARY_NAME; - Map options = new HashMap(); + Map options = Collections.emptyMap(); if (Platform.isWindows()) { - options.put(Library.OPTION_FUNCTION_MAPPER, new FunctionMapper() { + options = Collections.singletonMap(Library.OPTION_FUNCTION_MAPPER, new FunctionMapper() { + @Override public String getFunctionName(NativeLibrary library, Method method) { String name = method.getName(); - if ("getpid".equals(name)) { + if ("getpid".equals(name)) { name = "_getpid"; } return name; } }); } - CInterface clib = (CInterface) - Native.loadLibrary(cname, CInterface.class, options); + CInterface clib = Native.loadLibrary(cname, CInterface.class, options); /////////////////////////////////////////// // getpid @@ -251,50 +259,46 @@ // memset start = System.currentTimeMillis(); for (int i=0;i < COUNT;i++) { - presult = clib.memset(null, 0, 0); + Pointer presult = clib.memset(null, 0, 0); } delta = System.currentTimeMillis() - start; System.out.println("memset (JNA interface): " + delta + "ms"); f = NativeLibrary.getInstance(cname).getFunction("memset"); - args = new Object[] { null, new Integer(0), new Integer(0)}; + args = new Object[] { null, Integer.valueOf(0), Integer.valueOf(0)}; start = System.currentTimeMillis(); for (int i=0;i < COUNT;i++) { - presult = f.invokePointer(args); + Pointer presult = f.invokePointer(args); } delta = System.currentTimeMillis() - start; System.out.println("memset (JNA function): " + delta + "ms"); start = System.currentTimeMillis(); for (int i=0;i < COUNT;i++) { - presult = CLibrary.memset((Pointer)null, 0, new CLibrary.size_t(0)); + Pointer presult = CLibrary.memset((Pointer)null, 0, new CLibrary.size_t(0)); } delta = System.currentTimeMillis() - start; System.out.println("memset (JNA direct Pointer/size_t): " + delta + "ms"); start = System.currentTimeMillis(); if (Native.POINTER_SIZE == 4) { for (int i=0;i < COUNT;i++) { - presult = CLibrary.memset((Pointer)null, 0, 0); + Pointer presult = CLibrary.memset((Pointer)null, 0, 0); } - } - else { + } else { for (int i=0;i < COUNT;i++) { - presult = CLibrary.memset((Pointer)null, 0, 0L); + Pointer presult = CLibrary.memset((Pointer)null, 0, 0L); } } delta = System.currentTimeMillis() - start; System.out.println("memset (JNA direct Pointer/primitive): " + delta + "ms"); - int iresult; - long jresult; start = System.currentTimeMillis(); if (Native.POINTER_SIZE == 4) { for (int i=0;i < COUNT;i++) { - iresult = CLibrary.memset(0, 0, 0); + int iresult = CLibrary.memset(0, 0, 0); } - } - else { + } else { for (int i=0;i < COUNT;i++) { - jresult = CLibrary.memset(0L, 0, 0L); + long jresult = CLibrary.memset(0L, 0, 0L); } } delta = System.currentTimeMillis() - start; @@ -344,7 +348,7 @@ start = System.currentTimeMillis(); for (int i=0;i < COUNT;i++) { - Native.setMemory(0L, 0L, (byte)0); + Native.setMemory(Pointer.NULL, 0L, 0L, 0L, (byte)0); } delta = System.currentTimeMillis() - start; System.out.println("memset (JNI): " + delta + "ms"); @@ -354,7 +358,7 @@ String str = "performance test"; start = System.currentTimeMillis(); for (int i=0;i < COUNT;i++) { - iresult = clib.strlen(str); + int iresult = clib.strlen(str); } delta = System.currentTimeMillis() - start; System.out.println("strlen (JNA interface): " + delta + "ms"); @@ -363,28 +367,28 @@ args = new Object[] { str }; start = System.currentTimeMillis(); for (int i=0;i < COUNT;i++) { - iresult = f.invokeInt(args); + int iresult = f.invokeInt(args); } delta = System.currentTimeMillis() - start; System.out.println("strlen (JNA function): " + delta + "ms"); start = System.currentTimeMillis(); for (int i=0;i < COUNT;i++) { - iresult = CLibrary.strlen(str); + int iresult = CLibrary.strlen(str); } delta = System.currentTimeMillis() - start; System.out.println("strlen (JNA direct - String): " + delta + "ms"); start = System.currentTimeMillis(); for (int i=0;i < COUNT;i++) { - iresult = CLibrary.strlen(new NativeString(str).getPointer()); + int iresult = CLibrary.strlen(new NativeString(str).getPointer()); } delta = System.currentTimeMillis() - start; System.out.println("strlen (JNA direct - Pointer): " + delta + "ms"); start = System.currentTimeMillis(); for (int i=0;i < COUNT;i++) { - iresult = CLibrary.strlen(Native.toByteArray(str)); + int iresult = CLibrary.strlen(Native.toByteArray(str)); } delta = System.currentTimeMillis() - start; System.out.println("strlen (JNA direct - byte[]): " + delta + "ms"); @@ -395,7 +399,7 @@ b.position(0); b.put(bytes); b.put((byte)0); - iresult = CLibrary.strlen(b); + int iresult = CLibrary.strlen(b); } delta = System.currentTimeMillis() - start; System.out.println("strlen (JNA direct - Buffer): " + delta + "ms"); @@ -414,7 +418,7 @@ b.put(str.getBytes()); b.put((byte)0); Native.ffi_call(cif, f.peer, resp, argv); - iresult = b.getInt(4); + int iresult = b.getInt(4); } delta = System.currentTimeMillis() - start; } @@ -432,7 +436,7 @@ b.put(str.getBytes()); b.put((byte)0); Native.ffi_call(cif, f.peer, resp, argv); - jresult = b.getLong(8); + long jresult = b.getLong(8); } delta = System.currentTimeMillis() - start; } @@ -473,9 +477,10 @@ /////////////////////////////////////////// // Callbacks - TestInterface tlib = (TestInterface)Native.loadLibrary("testlib", TestInterface.class); + TestInterface tlib = Native.loadLibrary("testlib", TestInterface.class); start = System.currentTimeMillis(); TestInterface.Int32Callback cb = new TestInterface.Int32Callback() { + @Override public int invoke(int arg1, int arg2) { return arg1 + arg2; } @@ -492,6 +497,7 @@ start = System.currentTimeMillis(); TestInterface.NativeLongCallback nlcb = new TestInterface.NativeLongCallback() { + @Override public NativeLong invoke(NativeLong arg1, NativeLong arg2) { return new NativeLong(arg1.longValue() + arg2.longValue()); } diff -Nru libjna-java-4.2.2/test/com/sun/jna/PlatformTest.java libjna-java-4.4.0/test/com/sun/jna/PlatformTest.java --- libjna-java-4.2.2/test/com/sun/jna/PlatformTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/PlatformTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2013 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; @@ -20,68 +31,83 @@ public void testOSPrefix() { assertEquals("Wrong resource path", "win32-x86", Platform.getNativeLibraryResourcePrefix(Platform.WINDOWS, - "x86", "Windows")); + "x86", "Windows", false)); assertEquals("Wrong resource path Windows/i386", "win32-x86", Platform.getNativeLibraryResourcePrefix(Platform.WINDOWS, - "i386", "Windows")); + "i386", "Windows", false)); assertEquals("Wrong resource path Windows CE/arm", "w32ce-arm", Platform.getNativeLibraryResourcePrefix(Platform.WINDOWSCE, - "arm", "Windows CE")); + "arm", "Windows CE", false)); assertEquals("Wrong resource path Mac/x86", "darwin", Platform.getNativeLibraryResourcePrefix(Platform.MAC, - "x86", "Darwin")); + "x86", "Darwin", false)); assertEquals("Wrong resource path Mac/x86", "darwin", Platform.getNativeLibraryResourcePrefix(Platform.MAC, - "i386", "Darwin")); + "i386", "Darwin", false)); assertEquals("Wrong resource path Mac/x86_64", "darwin", Platform.getNativeLibraryResourcePrefix(Platform.MAC, - "x86_64", "Mac")); + "x86_64", "Mac", false)); assertEquals("Wrong resource path Solaris/sparc", "sunos-sparc", Platform.getNativeLibraryResourcePrefix(Platform.SOLARIS, - "sparc", "Solaris")); + "sparc", "Solaris", false)); assertEquals("Wrong resource path SunOS/sparcv9", "sunos-sparcv9", Platform.getNativeLibraryResourcePrefix(Platform.SOLARIS, - "sparcv9", "SunOS")); + "sparcv9", "SunOS", false)); assertEquals("Wrong resource path Linux/i386", "linux-x86", Platform.getNativeLibraryResourcePrefix(Platform.LINUX, - "i386", "Linux/Gnu")); + "i386", "Linux/Gnu", false)); assertEquals("Wrong resource path Linux/x86", "linux-x86", Platform.getNativeLibraryResourcePrefix(Platform.LINUX, - "x86", "Linux")); + "x86", "Linux", false)); assertEquals("Wrong resource path Linux/x86", "linux-x86-64", Platform.getNativeLibraryResourcePrefix(Platform.LINUX, - "x86_64", "Linux")); + "x86_64", "Linux", false)); assertEquals("Wrong resource path Linux/x86", "linux-x86-64", Platform.getNativeLibraryResourcePrefix(Platform.LINUX, - "amd64", "Linux")); + "amd64", "Linux", false)); assertEquals("Wrong resource path Linux/ppc", "linux-ppc", Platform.getNativeLibraryResourcePrefix(Platform.LINUX, - "powerpc", "Linux")); + "powerpc", "Linux", false)); assertEquals("Wrong resource path Linux/sparcv9", "linux-sparcv9", Platform.getNativeLibraryResourcePrefix(Platform.LINUX, - "sparcv9", "Linux")); + "sparcv9", "Linux", false)); + assertEquals("Wrong resource path Linux/arm (hardfloat)", "linux-arm", + Platform.getNativeLibraryResourcePrefix(Platform.LINUX, + "arm", "Linux/Gnu", false)); + assertEquals("Wrong resource path Linux/arm (softfloat)", "linux-armel", + Platform.getNativeLibraryResourcePrefix(Platform.LINUX, + "arm", "Linux/Gnu", true)); assertEquals("Wrong resource path OpenBSD/x86", "openbsd-x86", Platform.getNativeLibraryResourcePrefix(Platform.OPENBSD, - "x86", "OpenBSD")); + "x86", "OpenBSD", false)); assertEquals("Wrong resource path FreeBSD/x86", "freebsd-x86", Platform.getNativeLibraryResourcePrefix(Platform.FREEBSD, - "x86", "FreeBSD")); + "x86", "FreeBSD", false)); assertEquals("Wrong resource path GNU/kFreeBSD/x86", "kfreebsd-x86", Platform.getNativeLibraryResourcePrefix(Platform.KFREEBSD, - "x86", "GNU/kFreeBSD")); + "x86", "GNU/kFreeBSD", false)); assertEquals("Wrong resource path NetBSD/x86", "netbsd-x86", Platform.getNativeLibraryResourcePrefix(Platform.NETBSD, - "x86", "NetBSD")); + "x86", "NetBSD", false)); assertEquals("Wrong resource path Linux/armv7l (android)", "android-arm", Platform.getNativeLibraryResourcePrefix(Platform.ANDROID, - "armv7l", "Linux")); + "armv7l", "Linux", false)); assertEquals("Wrong resource path other/other", "name-ppc", Platform.getNativeLibraryResourcePrefix(Platform.UNSPECIFIED, - "PowerPC", "Name Of System")); + "PowerPC", "Name Of System", false)); } + public void testSystemProperty() { + String demoOverride = "demoOverride"; + assertFalse(demoOverride.equals(Platform.getNativeLibraryResourcePrefix())); + + System.setProperty("jna.prefix", demoOverride); + assertTrue(demoOverride.equals(Platform.getNativeLibraryResourcePrefix())); + + System.clearProperty("jna.prefix"); + } public static void main(String[] args) { junit.textui.TestRunner.run(PlatformTest.class); diff -Nru libjna-java-4.2.2/test/com/sun/jna/PointerBufferTest.java libjna-java-4.4.0/test/com/sun/jna/PointerBufferTest.java --- libjna-java-4.2.2/test/com/sun/jna/PointerBufferTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/PointerBufferTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Wayne Meissner, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

        - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; @@ -19,12 +30,6 @@ import java.nio.FloatBuffer; import java.nio.IntBuffer; import java.nio.LongBuffer; -import java.util.Arrays; -import java.util.Iterator; -import java.util.Map; -import java.util.Properties; -import java.util.Map.Entry; - import junit.framework.TestCase; diff -Nru libjna-java-4.2.2/test/com/sun/jna/PointerTest.java libjna-java-4.4.0/test/com/sun/jna/PointerTest.java --- libjna-java-4.2.2/test/com/sun/jna/PointerTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/PointerTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,15 +1,26 @@ /* Copyright (c) 2007 Wayne Meissner, All Rights Reserved * Copyright (c) 2007-2013 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

        - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; @@ -18,16 +29,11 @@ import java.lang.reflect.Modifier; import java.lang.reflect.InvocationTargetException; import java.util.Arrays; -import java.util.Iterator; -import java.util.Map; -import java.util.Properties; -import java.util.Map.Entry; - import junit.framework.TestCase; public class PointerTest extends TestCase { - + private static final String UNICODE = "[\u0444]"; public void testGetNativeLong() { @@ -182,26 +188,26 @@ assertNull("Array element should be null", arr[0]); } - private Object defaultArg(Class type) { + private Object defaultArg(Class type) { if (type == boolean.class || type == Boolean.class) return Boolean.FALSE; - if (type == byte.class || type == Byte.class) return new Byte((byte)0); - if (type == char.class || type == Character.class) return new Character((char)0); - if (type == short.class || type == Short.class) return new Short((short)0); - if (type == int.class || type == Integer.class) return new Integer(0); - if (type == long.class || type == Long.class) return new Long(0); - if (type == float.class || type == Float.class) return new Float(0); - if (type == double.class || type == Double.class) return new Double(0); + if (type == byte.class || type == Byte.class) return Byte.valueOf((byte)0); + if (type == char.class || type == Character.class) return Character.valueOf((char)0); + if (type == short.class || type == Short.class) return Short.valueOf((short)0); + if (type == int.class || type == Integer.class) return Integer.valueOf(0); + if (type == long.class || type == Long.class) return Long.valueOf(0L); + if (type == float.class || type == Float.class) return Float.valueOf(0); + if (type == double.class || type == Double.class) return Double.valueOf(0); if (type == NativeLong.class) return new NativeLong(0); return null; } public void testOpaquePointer() throws Exception { Pointer p = Pointer.createConstant(0); - Class cls = p.getClass(); + Class cls = p.getClass(); Method[] methods = cls.getMethods(); for (int i=0;i < methods.length;i++) { Method m = methods[i]; - Class[] argTypes = m.getParameterTypes(); + Class[] argTypes = m.getParameterTypes(); try { Object[] args = new Object[argTypes.length]; for (int arg=0;arg < args.length;arg++) { diff -Nru libjna-java-4.2.2/test/com/sun/jna/PrematureGCTest.java libjna-java-4.4.0/test/com/sun/jna/PrematureGCTest.java --- libjna-java-4.2.2/test/com/sun/jna/PrematureGCTest.java 1970-01-01 00:00:00.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/PrematureGCTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -0,0 +1,51 @@ +/** + * 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 org.junit.Test; + +/** + * Reported in https://github.com/java-native-access/jna/issues/664 + * + * For the + */ +public class PrematureGCTest { + @Test + public void testGC() { + Native.setProtected(false); + + // This code below is reduced from a different test. (I forget which.) + new Memory(4); + + // The code below comes from NativeTest.testLongStringGeneration. + StringBuilder buf = new StringBuilder(); + final int MAX = 200000; + for (int i = 0; i < MAX; i++) { + buf.append("aaaaaaaaaa"); + } + String s1 = buf.toString(); + Memory m = new Memory(( MAX * 10 + 1) * Native.WCHAR_SIZE); + m.setWideString(0, s1); + m.getWideString(0); + } +} diff -Nru libjna-java-4.2.2/test/com/sun/jna/ReturnTypesTest.java libjna-java-4.4.0/test/com/sun/jna/ReturnTypesTest.java --- libjna-java-4.2.2/test/com/sun/jna/ReturnTypesTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/ReturnTypesTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,22 +1,31 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

        - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.Arrays; -import java.util.HashMap; +import java.nio.charset.Charset; +import java.util.Collections; import java.util.List; -import java.util.Map; - import junit.framework.TestCase; import com.sun.jna.ReturnTypesTest.TestLibrary.SimpleStructure; @@ -34,50 +43,61 @@ private static final float FLOAT_MAGIC = -118.625f; public static interface TestLibrary extends Library { - + public static class SimpleStructure extends Structure { + public static final List FIELDS = createFieldsOrder("value"); public double value; public static int allocations = 0; public SimpleStructure() { } public SimpleStructure(Pointer p) { super(p); read(); } + @Override protected void allocateMemory(int size) { super.allocateMemory(size); ++allocations; } - protected List getFieldOrder() { - return Arrays.asList(new String[] { "value" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } - + public static class TestSmallStructure extends Structure { public static class ByValue extends TestSmallStructure implements Structure.ByValue { } + + public static final List FIELDS = createFieldsOrder("c1", "c2", "s"); public byte c1; public byte c2; public short s; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "c1", "c2", "s" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } public static class TestStructure extends Structure { public static class ByValue extends TestStructure implements Structure.ByValue { } + + public static final List FIELDS = createFieldsOrder("c", "s", "i", "j", "inner"); public byte c; public short s; public int i; public long j; public SimpleStructure inner; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "c", "s", "i", "j", "inner" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } - - class CheckFieldAlignment extends Structure { + + public static class CheckFieldAlignment extends Structure { + public static final List FIELDS = createFieldsOrder("int32Field", "int64Field", "floatField", "doubleField"); public int int32Field = 1; public long int64Field = 2; public float floatField = 3f; public double doubleField = 4d; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "int32Field", "int64Field", "floatField", "doubleField" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } @@ -109,28 +129,28 @@ } TestLibrary lib; + @Override protected void setUp() { - lib = (TestLibrary)Native.loadLibrary("testlib", TestLibrary.class); + lib = Native.loadLibrary("testlib", TestLibrary.class); } - + + @Override protected void tearDown() { lib = null; } - + public void testReturnObject() throws Exception { - Map options = new HashMap() { { - put(Library.OPTION_ALLOW_OBJECTS, Boolean.TRUE); - }}; - lib = (TestLibrary)Native.loadLibrary("testlib", TestLibrary.class, options); + lib = Native.loadLibrary("testlib", TestLibrary.class, Collections.singletonMap(Library.OPTION_ALLOW_OBJECTS, Boolean.TRUE)); assertNull("null value not returned", lib.returnObjectArgument(null)); final Object VALUE = new Object() { + @Override public String toString() { return getName(); } }; assertEquals("Wrong object returned", VALUE, lib.returnObjectArgument(VALUE)); } - + public void testReturnObjectUnsupported() throws Exception { try { lib.returnObjectArgument(new TestLibrary.TestObject()); @@ -152,30 +172,30 @@ public void testInvokeInt() { assertEquals("Expect 32-bit zero", 0, lib.returnInt32Zero()); - assertEquals("Expect 32-bit magic", - "12345678", + assertEquals("Expect 32-bit magic", + "12345678", Integer.toHexString(lib.returnInt32Magic())); } public void testInvokeLong() { assertEquals("Expect 64-bit zero", 0L, lib.returnInt64Zero()); - assertEquals("Expect 64-bit magic", - "123456789abcdef0", + assertEquals("Expect 64-bit magic", + "123456789abcdef0", Long.toHexString(lib.returnInt64Magic())); } - + public void testInvokeNativeLong() { if (NativeLong.SIZE == 4) { assertEquals("Expect 32-bit zero", new NativeLong(0), lib.returnLongZero()); - assertEquals("Expect 32-bit magic", - "12345678", + assertEquals("Expect 32-bit magic", + "12345678", Integer.toHexString(lib.returnLongMagic().intValue())); - + } else { - assertEquals("Expect 64-bit zero", new NativeLong(0L), + assertEquals("Expect 64-bit zero", new NativeLong(0L), lib.returnLongZero()); - assertEquals("Expect 64-bit magic", - "123456789abcdef0", + assertEquals("Expect 64-bit magic", + "123456789abcdef0", Long.toHexString(lib.returnLongMagic().longValue())); } } @@ -186,6 +206,7 @@ size_t returnInt64Magic(); } public static class size_t extends IntegerType { + private static final long serialVersionUID = 1L; public size_t() { this(0); } @@ -200,22 +221,25 @@ public Custom(int value) { this.value = value; } + @Override public Object fromNative(Object nativeValue, FromNativeContext context) { return new Custom(((Integer)nativeValue).intValue()); } - public Class nativeType() { + @Override + public Class nativeType() { return Integer.class; } + @Override public Object toNative() { - return new Integer(value); + return Integer.valueOf(value); } + @Override public boolean equals(Object o) { return o instanceof Custom && ((Custom)o).value == value; } } protected NativeMappedLibrary loadNativeMappedLibrary() { - return (NativeMappedLibrary) - Native.loadLibrary("testlib", NativeMappedLibrary.class); + return Native.loadLibrary("testlib", NativeMappedLibrary.class); } public void testInvokeNativeMapped() { @@ -224,24 +248,24 @@ final long MAGIC64 = 0x123456789ABCDEF0L; final Custom EXPECTED = new Custom(MAGIC); assertEquals("NativeMapped 'Custom' result not mapped", EXPECTED, lib.returnInt32Argument(MAGIC)); - - assertEquals("NativeMapped IntegerType result not mapped (32)", + + assertEquals("NativeMapped IntegerType result not mapped (32)", new size_t(MAGIC), lib.returnInt32Magic()); if (Native.SIZE_T_SIZE == 8) { - assertEquals("NativeMapped IntegerType result not mapped (64)", + assertEquals("NativeMapped IntegerType result not mapped (64)", new size_t(MAGIC64), lib.returnInt64Magic()); } } public void testInvokeFloat() { assertEquals("Expect float zero", 0f, lib.returnFloatZero(), 0d); - assertEquals("Expect float magic", + assertEquals("Expect float magic", FLOAT_MAGIC, lib.returnFloatMagic(), 0d); } public void testInvokeDouble() { assertEquals("Expect double zero", 0d, lib.returnDoubleZero(), 0d); - assertEquals("Expect double magic", + assertEquals("Expect double magic", DOUBLE_MAGIC, lib.returnDoubleMagic(), 0d); } @@ -249,26 +273,26 @@ public void testInvokeString() { assertEquals("Expect String magic", MAGIC, lib.returnStringMagic()); } - + public void testInvokeWString() { WString s = lib.returnWStringMagic(); assertEquals("Wrong length", MAGIC.length(), s.toString().length()); assertEquals("Expect WString magic", new WString(MAGIC), s); } - + public void testInvokeStructure() { SimpleStructure.allocations = 0; SimpleStructure s = lib.returnStaticTestStructure(); assertEquals("Expect test structure magic", DOUBLE_MAGIC, s.value, 0d); - // Optimized structure allocation + // Optimized structure allocation assertEquals("Returned Structure should allocate no memory", 0, SimpleStructure.allocations); } - + public void testInvokeNullStructure() { SimpleStructure s = lib.returnNullTestStructure(); assertNull("Expect null structure return", s); } - + public void testReturnSmallStructureByValue() { TestSmallStructure s = lib.returnSmallStructureByValue(); assertNotNull("Returned structure must not be null", s); @@ -276,7 +300,7 @@ assertEquals("Wrong char field value (2)", 2, s.c2); assertEquals("Wrong short field value", 3, s.s); } - + public void testReturnStructureByValue() { TestStructure s = lib.returnStructureByValue(); assertNotNull("Returned structure must not be null", s); @@ -288,7 +312,7 @@ assertNotNull("Structure not initialized", s.inner); assertEquals("Wrong inner structure value", 5, s.inner.value, 0); } - + public void testReturnPointerArray() { Pointer value = new Memory(10); Pointer[] input = { @@ -302,7 +326,8 @@ } public void testReturnStringArray() { - final String VALUE = getName() + UNICODE; + Charset charset = Charset.forName(Native.getDefaultStringEncoding()); + final String VALUE = getName() + charset.decode(charset.encode(UNICODE)); String[] input = { VALUE, null, }; @@ -328,5 +353,5 @@ public static void main(java.lang.String[] argList) { junit.textui.TestRunner.run(ReturnTypesTest.class); } - + } diff -Nru libjna-java-4.2.2/test/com/sun/jna/StructureBufferFieldTest.java libjna-java-4.4.0/test/com/sun/jna/StructureBufferFieldTest.java --- libjna-java-4.2.2/test/com/sun/jna/StructureBufferFieldTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/StructureBufferFieldTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,21 +1,31 @@ /* Copyright (c) 2007-2009 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

        - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.nio.Buffer; import java.nio.ByteBuffer; import java.nio.DoubleBuffer; -import java.util.Arrays; import java.util.List; import junit.framework.TestCase; @@ -31,10 +41,12 @@ } static class BufferStructure extends Structure { + public static final List FIELDS = createFieldsOrder("buffer", "dbuffer"); public Buffer buffer; public DoubleBuffer dbuffer; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "buffer", "dbuffer" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } public void testBufferFieldWriteNULL() { diff -Nru libjna-java-4.2.2/test/com/sun/jna/StructureByValueTest.java libjna-java-4.4.0/test/com/sun/jna/StructureByValueTest.java --- libjna-java-4.2.2/test/com/sun/jna/StructureByValueTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/StructureByValueTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,18 +1,28 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

        - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.Arrays; import java.util.List; import junit.framework.TestCase; @@ -26,9 +36,11 @@ public static class TestNativeMappedInStructure extends Structure { public static class ByValue extends TestNativeMappedInStructure implements Structure.ByValue { } + public static final List FIELDS = createFieldsOrder("field"); public NativeLong field; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "field" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } public void testNativeMappedInByValue() { @@ -45,43 +57,55 @@ TestLibrary lib; + @Override protected void setUp() { - lib = (TestLibrary)Native.loadLibrary("testlib", TestLibrary.class); + lib = Native.loadLibrary("testlib", TestLibrary.class); } + @Override protected void tearDown() { lib = null; } public static abstract class ByValueStruct extends Structure implements Structure.ByValue { } public static class ByValue8 extends ByValueStruct { + public static final List FIELDS = createFieldsOrder("data"); public byte data; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "data" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } public static class ByValue16 extends ByValueStruct { + public static final List FIELDS = createFieldsOrder("data"); public short data; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "data" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } public static class ByValue32 extends ByValueStruct { + public static final List FIELDS = createFieldsOrder("data"); public int data; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "data" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } public static class ByValue64 extends ByValueStruct { + public static final List FIELDS = createFieldsOrder("data"); public long data; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "data" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } public static class ByValue128 extends ByValueStruct { + public static final List FIELDS = createFieldsOrder("data", "data1"); public long data, data1; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "data", "data1" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } final long MAGIC = 0x0123456789ABCDEFL; diff -Nru libjna-java-4.2.2/test/com/sun/jna/StructureFieldOrderInspector.java libjna-java-4.4.0/test/com/sun/jna/StructureFieldOrderInspector.java --- libjna-java-4.2.2/test/com/sun/jna/StructureFieldOrderInspector.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/StructureFieldOrderInspector.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,3 +1,25 @@ +/** + * 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 org.reflections.Reflections; @@ -32,7 +54,7 @@ * @param classDeclaredInSourceTreeToSearch a class who's source tree will be searched for Structure sub types. * @param ignoreConstructorError list of classname prefixes for which to ignore construction errors. */ - public static void batchCheckStructureGetFieldOrder(final Class classDeclaredInSourceTreeToSearch, + public static void batchCheckStructureGetFieldOrder(final Class classDeclaredInSourceTreeToSearch, final List ignoreConstructorError) { final Set> classes = StructureFieldOrderInspector.findSubTypesOfStructure(classDeclaredInSourceTreeToSearch); @@ -62,7 +84,7 @@ * @param classDeclaredInSourceTreeToSearch a class who's source tree will be searched for Structure sub types. * @param ignoreConstructorError list of classname prefixes for which to ignore construction errors. */ - public static void checkStructureGetFieldOrder(final Class classDeclaredInSourceTreeToSearch, + public static void checkStructureGetFieldOrder(final Class classDeclaredInSourceTreeToSearch, final List ignoreConstructorError) { final Set> classes = StructureFieldOrderInspector.findSubTypesOfStructure(classDeclaredInSourceTreeToSearch); @@ -74,7 +96,7 @@ /** * Find all classes that extend {@link Structure}. */ - public static Set> findSubTypesOfStructure(final Class classDeclaredInSourceTreeToSearch) { + public static Set> findSubTypesOfStructure(final Class classDeclaredInSourceTreeToSearch) { // use: http://code.google.com/p/reflections/ @@ -142,9 +164,9 @@ if (!methodGetFieldOrder.isAccessible()) { methodGetFieldOrder.setAccessible(true); } - final List methodCallFieldList; + final List methodCallFieldList; try { - methodCallFieldList = (List) methodGetFieldOrder.invoke(structure); + methodCallFieldList = (List) methodGetFieldOrder.invoke(structure); } catch (IllegalAccessException e) { throw new RuntimeException("Could not invoke getFieldOrder() on Structure sub type: " + structureSubType.getName(), e); } catch (InvocationTargetException e) { @@ -152,7 +174,7 @@ } final Field[] actualFields = structureSubType.getFields(); // include fields from super classes - final List actualFieldNames = new ArrayList(actualFields.length); + final List actualFieldNames = new ArrayList(actualFields.length); for (final Field field : actualFields) { // ignore static fields if (!Modifier.isStatic(field.getModifiers())) { diff -Nru libjna-java-4.2.2/test/com/sun/jna/StructureFieldOrderInspectorTest.java libjna-java-4.4.0/test/com/sun/jna/StructureFieldOrderInspectorTest.java --- libjna-java-4.2.2/test/com/sun/jna/StructureFieldOrderInspectorTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/StructureFieldOrderInspectorTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,9 +1,32 @@ +/** + * 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 junit.framework.TestCase; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Properties; import java.util.Set; @@ -19,11 +42,13 @@ private String origPropJNANoSys; + @Override protected void setUp() { origPropJNANoSys = System.getProperty("jna.nosys"); System.setProperty("jna.nosys", "true"); // would be set by ant script, set here for IDE usage } + @Override protected void tearDown() { if (origPropJNANoSys == null) { Properties props = (Properties)System.getProperties().clone(); @@ -56,13 +81,12 @@ private static final class MyStructMissingField extends Structure { - @SuppressWarnings("UnusedDeclaration") public String missingDeclaredField; @Override - protected List getFieldOrder() { + protected List getFieldOrder() { //noinspection unchecked - return Arrays.asList(); + return Collections.emptyList(); } } public void testCheckMethodGetFieldOrderMissingField() throws Exception { @@ -76,7 +100,7 @@ private static final class MyStructExtraField extends Structure { @Override - protected List getFieldOrder() { + protected List getFieldOrder() { return Arrays.asList("extraField"); } } @@ -91,13 +115,11 @@ private static final class MyStructStaticField extends Structure { - @SuppressWarnings("UnusedDeclaration") public long instanceField; - @SuppressWarnings("UnusedDeclaration") public static long myStaticField = -1; @Override - protected List getFieldOrder() { + protected List getFieldOrder() { return Arrays.asList("instanceField"); } } @@ -107,11 +129,10 @@ private static class MyStructSuper extends Structure { - @SuppressWarnings("UnusedDeclaration") public long instanceField; @Override - protected List getFieldOrder() { + protected List getFieldOrder() { return Arrays.asList("instanceField"); } } diff -Nru libjna-java-4.2.2/test/com/sun/jna/StructureTest.java libjna-java-4.4.0/test/com/sun/jna/StructureTest.java --- libjna-java-4.2.2/test/com/sun/jna/StructureTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/StructureTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,22 +1,35 @@ /* Copyright (c) 2007-2009 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

        - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.nio.charset.Charset; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.Set; +import java.util.concurrent.atomic.AtomicReference; import junit.framework.TestCase; @@ -40,8 +53,9 @@ public void testSimpleSize() throws Exception { class TestStructure extends Structure { public int field; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "field" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("field"); } } Structure s = new TestStructure(); @@ -51,8 +65,9 @@ public void testInitializeFromPointer() { class TestStructureX extends Structure { public int field1, field2; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "field1", "field2" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("field1", "field2"); } public TestStructureX() { } @@ -73,8 +88,9 @@ public void testInitializeWithTypeMapper() { class TestStructure extends Structure { public int field; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "field" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("field"); } public TestStructure(TypeMapper m) { super(ALIGN_DEFAULT, m); @@ -87,23 +103,26 @@ // must be public to populate array public static class TestAllocStructure extends Structure { + public static final List FIELDS = createFieldsOrder("f0", "f1", "f2", "f3"); public int f0; public int f1; public int f2; public int f3; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "f0", "f1", "f2", "f3" }); + + @Override + protected List getFieldOrder() { + return FIELDS; } } - public void testFieldsAllocated() { class TestStructure extends Structure { public TestStructure() { } public TestStructure(Pointer p) { super(p); } public int field; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "field" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("field"); } public int fieldCount() { ensureAllocated(); return fields().size(); } } @@ -118,8 +137,9 @@ class TestStructure extends Structure { public TestStructure(Pointer p) { super(p); } public int field; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "field" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("field"); } } try { @@ -154,8 +174,9 @@ public long l; public float f; public double d; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "b", "s", "i", "l", "f", "d" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("b", "s", "i", "l", "f", "d"); } } Structure s = new TestStructure(); @@ -173,8 +194,9 @@ public long l; public float f; public double d; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "b", "s", "i", "l", "f", "d" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("b", "s", "i", "l", "f", "d"); } } Structure s = new TestStructure(); @@ -184,6 +206,7 @@ public static abstract class FilledStructure extends Structure { private boolean initialized; + @Override protected void ensureAllocated() { super.ensureAllocated(); if (!initialized) { @@ -196,48 +219,60 @@ } // Do NOT change the order of naming w/o changing testlib.c as well public static class TestStructure0 extends FilledStructure { + public static final List FIELDS = createFieldsOrder("field0", "field1"); public byte field0 = 0x01; public short field1 = 0x0202; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "field0", "field1" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } public static class TestStructure1 extends FilledStructure { + public static final List FIELDS = createFieldsOrder("field0", "field1"); public byte field0 = 0x01; public int field1 = 0x02020202; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "field0", "field1" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } public static class TestStructure2 extends FilledStructure { + public static final List FIELDS = createFieldsOrder("field0", "field1"); public short field0 = 0x0101; public int field1 = 0x02020202; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "field0", "field1" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } public static class TestStructure3 extends FilledStructure { + public static final List FIELDS = createFieldsOrder("field0", "field1", "field2"); public int field0 = 0x01010101; public short field1 = 0x0202; public int field2 = 0x03030303; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "field0", "field1", "field2" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } public static class TestStructure4 extends FilledStructure { + public static final List FIELDS = createFieldsOrder("field0", "field1", "field2", "field3"); public int field0 = 0x01010101; public long field1 = 0x0202020202020202L; public int field2 = 0x03030303; public long field3 = 0x0404040404040404L; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "field0", "field1", "field2", "field3" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } public static class TestStructure5 extends FilledStructure { + public static final List FIELDS = createFieldsOrder("field0", "field1"); public long field0 = 0x0101010101010101L; public byte field1 = 0x02; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "field0", "field1" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } public interface SizeTest extends Library { @@ -245,8 +280,8 @@ } private void testStructureSize(int index) { try { - SizeTest lib = (SizeTest)Native.loadLibrary("testlib", SizeTest.class); - Class cls = Class.forName(getClass().getName() + "$TestStructure" + index); + SizeTest lib = Native.loadLibrary("testlib", SizeTest.class); + Class cls = Class.forName(getClass().getName() + "$TestStructure" + index); Structure s = Structure.newInstance(cls); assertEquals("Incorrect size for structure " + index + "=>" + s.toString(true), lib.getStructureSize(index), s.size()); } @@ -279,11 +314,11 @@ } private void testAlignStruct(int index) { - AlignmentTest lib = (AlignmentTest)Native.loadLibrary("testlib", AlignmentTest.class); + AlignmentTest lib = Native.loadLibrary("testlib", AlignmentTest.class); try { IntByReference offset = new IntByReference(); LongByReference value = new LongByReference(); - Class cls = Class.forName(getClass().getName() + "$TestStructure" + index); + Class cls = Class.forName(getClass().getName() + "$TestStructure" + index); Structure s = (Structure)cls.newInstance(); int result = lib.testStructureAlignment(s, index, offset, value); assertEquals("Wrong native value at field " + result @@ -316,8 +351,9 @@ public void testStructureWithNoFields() { class TestStructure extends Structure { - protected List getFieldOrder() { - return Arrays.asList(new String[] {}); + @Override + protected List getFieldOrder() { + return Collections.emptyList(); } } try { @@ -325,14 +361,16 @@ fail("Structure should not be instantiable if it has no public member fields"); } catch(IllegalArgumentException e) { + // expected - ignored } } public void testStructureWithOnlyNonPublicMemberFields() { class TestStructure extends Structure { int field; - protected List getFieldOrder() { - return Arrays.asList(new String[] {"field"}); + @Override + protected List getFieldOrder() { + return Arrays.asList("field"); } } try { @@ -340,6 +378,7 @@ fail("Structure should not be instantiable if it has no public member fields"); } catch(Error e) { + // expected - ignored } } @@ -353,24 +392,29 @@ public ByReference() { } public ByReference(Pointer p) { super(p); } } + + public static final List FIELDS = createFieldsOrder("x", "y"); public int x = 1, y = 2; public PublicTestStructure() { } public PublicTestStructure(Pointer p) { super(p); read(); } public static int allocations = 0; + @Override protected void allocateMemory(int size) { super.allocateMemory(size); ++allocations; } - protected List getFieldOrder() { - return Arrays.asList(new String[] { "x", "y" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } public void testStructureField() { class TestStructure extends Structure { public PublicTestStructure s1, s2; public int after; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "s1", "s2", "after" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("s1", "s2", "after"); } } TestStructure s = new TestStructure(); @@ -398,8 +442,9 @@ class TestStructure extends Structure { public PublicTestStructure.ByValue s1, s2; public int after; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "s1", "s2", "after" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("s1", "s2", "after"); } } TestStructure s = new TestStructure(); @@ -423,7 +468,7 @@ s.s2.getPointer()); } - static class TestUnion extends Union { + public static class TestUnion extends Union { public int u_int; public float u_float; public double u_double; @@ -433,8 +478,9 @@ public long s_long; public TestUnion s_union; public int s_int; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "s_long", "s_union", "s_int" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("s_long", "s_union", "s_int"); } } TestStructure s = new TestStructure(); @@ -445,6 +491,7 @@ public static class NonAllocatingTestStructure extends PublicTestStructure { public NonAllocatingTestStructure() { } public NonAllocatingTestStructure(Pointer p) { super(p); read(); } + @Override protected void allocateMemory(int size) { throw new Error("Memory unexpectedly allocated"); } @@ -458,8 +505,9 @@ class TestStructure extends Structure { public NonAllocatingTestStructure s1; public TestStructure() { } - protected List getFieldOrder() { - return Arrays.asList(new String[] { "s1" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("s1"); } } TestStructure ts = new TestStructure(); @@ -469,8 +517,9 @@ public void testPrimitiveArrayField() { class TestStructure extends Structure { public byte[] buffer = new byte[1024]; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "buffer" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("buffer"); } } TestStructure s = new TestStructure(); @@ -490,8 +539,9 @@ // initialized array elements public PublicTestStructure[] inner2 = (PublicTestStructure[]) new PublicTestStructure().toArray(2); - protected List getFieldOrder() { - return Arrays.asList(new String[] { "inner", "inner2" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("inner", "inner2"); } } TestStructure s = new TestStructure(); @@ -530,10 +580,13 @@ } public static class ToArrayTestStructure extends Structure { + public static final List FIELDS = createFieldsOrder("inner"); public PublicTestStructure[] inner = (PublicTestStructure[])new PublicTestStructure().toArray(2); - protected List getFieldOrder() { - return Arrays.asList(new String[] { "inner" }); + + @Override + protected List getFieldOrder() { + return FIELDS; } } public void testToArrayWithStructureArrayField() { @@ -550,8 +603,9 @@ public void testUninitializedNestedArrayFails() { class TestStructure extends Structure { public Pointer[] buffer; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "buffer" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("buffer"); } } Structure s = new TestStructure(); @@ -585,8 +639,9 @@ public float[] fa = new float[3]; public double[] da = new double[3]; public PublicTestStructure nested; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "z", "b", "c", "s", "i", "l", "f", "d", "ba", "ca", "sa", "ia", "la", "fa", "da", "nested" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("z", "b", "c", "s", "i", "l", "f", "d", "ba", "ca", "sa", "ia", "la", "fa", "da", "nested"); } } TestStructure s = new TestStructure(); @@ -645,8 +700,9 @@ public void testNativeLongSize() throws Exception { class TestStructure extends Structure { public NativeLong l; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "l" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("l"); } } Structure s = new TestStructure(); @@ -657,8 +713,9 @@ class TestStructure extends Structure { public int i; public NativeLong l; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "i", "l" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("i", "l"); } } TestStructure s = new TestStructure(); @@ -680,8 +737,9 @@ class TestStructure extends Structure { public int i; public NativeLong l; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "i", "l" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("i", "l"); } } TestStructure s = new TestStructure(); @@ -704,39 +762,45 @@ public void testMemoryField() { class MemoryFieldStructure extends Structure { public Memory m; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "m" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("m"); } } new MemoryFieldStructure().size(); } public void testDisallowFunctionPointerAsField() { - class BadFieldStructure extends Structure { + class DisallowFunctionPointer extends Structure { public Function cb; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "cb" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("cb"); } } try { - new BadFieldStructure().size(); + new DisallowFunctionPointer().size(); fail("Function fields should not be allowed"); } catch(IllegalArgumentException e) { + // expected - ignored } } public static class BadFieldStructure extends Structure { + public static final List FIELDS = createFieldsOrder("badField"); public Object badField; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "badField" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } public void testUnsupportedField() { class BadNestedStructure extends Structure { public BadFieldStructure badStruct = new BadFieldStructure(); - protected List getFieldOrder() { - return Arrays.asList(new String[] { "badStruct" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("badStruct"); } } try { @@ -744,8 +808,7 @@ fail("Should throw IllegalArgumentException on bad field"); } catch(IllegalArgumentException e) { - assertTrue("Exception should include field name: " + e, - e.getMessage().indexOf("badField") != -1); + assertTrue("Exception should include field name: " + e.getMessage(), e.getMessage().indexOf("badField") != -1); } try { new BadNestedStructure(); @@ -782,8 +845,9 @@ (PublicTestStructure.ByReference[])s.toArray(2); class TestStructure extends Structure { public PublicTestStructure.ByReference ref; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "ref" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("ref"); } } TestStructure ts = new TestStructure(); @@ -806,10 +870,12 @@ assertEquals("Array element not read: " + array[1], VALUE, array[1].y); } - static class CbStruct extends Structure { + public static class CbStruct extends Structure { + public static final List FIELDS = createFieldsOrder("cb"); public Callback cb; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "cb" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } public void testCallbackWrite() { @@ -821,32 +887,35 @@ s.write(); Pointer func = s.getPointer().getPointer(0); assertNotNull("Callback trampoline not set", func); - Map refs = CallbackReference.callbackMap; + Map refs = CallbackReference.callbackMap; assertTrue("Callback not cached", refs.containsKey(s.cb)); - CallbackReference ref = (CallbackReference)refs.get(s.cb); + CallbackReference ref = refs.get(s.cb); assertEquals("Wrong trampoline", ref.getTrampoline(), func); } public void testUninitializedArrayField() { class UninitializedArrayFieldStructure extends Structure { public byte[] array; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "array" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("array"); } } try { Structure s = new UninitializedArrayFieldStructure(); assertTrue("Invalid size: " + s.size(), s.size() > 0); fail("Uninitialized array field should cause write failure"); - } - catch(IllegalStateException e) { + } catch(IllegalStateException e) { + // expected } } public static class StructureWithArrayOfStructureField extends Structure { + public static final List FIELDS = createFieldsOrder("array"); public Structure[] array; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "array" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } public void testPlainStructureArrayField() { @@ -855,20 +924,25 @@ fail("Structure[] should not be allowed as a field of Structure"); } catch(IllegalArgumentException e) { + // expected - ignored } catch(Exception e) { fail("Wrong exception thrown when Structure[] field encountered in a Structure: " + e); } } - public void testPointerArrayField() { - class ArrayOfPointerStructure extends Structure { - final static int SIZE = 10; - public Pointer[] array = new Pointer[SIZE]; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "array" }); - } + public static class ArrayOfPointerStructure extends Structure { + public static final List FIELDS = createFieldsOrder("array"); + final static int SIZE = 10; + public Pointer[] array = new Pointer[SIZE]; + + @Override + protected List getFieldOrder() { + return FIELDS; } + } + + public void testPointerArrayField() { ArrayOfPointerStructure s = new ArrayOfPointerStructure(); int size = s.size(); assertEquals("Wrong size", ArrayOfPointerStructure.SIZE * Pointer.SIZE, size); @@ -879,14 +953,18 @@ assertEquals("Wrong first element", s.getPointer(), s.array[0]); } - public void testVolatileStructureField() { - class VolatileStructure extends Structure { - public volatile int counter; - public int value; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "counter", "value" }); - } + public static class VolatileStructure extends Structure { + public static final List FIELDS = createFieldsOrder("counter", "value"); + public volatile int counter; + public int value; + + @Override + protected List getFieldOrder() { + return FIELDS; } + } + + public void testVolatileStructureField() { VolatileStructure s = new VolatileStructure(); s.counter = 1; s.value = 1; @@ -904,24 +982,23 @@ } public static class StructureWithPointers extends Structure { + public static final List FIELDS = createFieldsOrder("s1", "s2"); public PublicTestStructure.ByReference s1; public PublicTestStructure.ByReference s2; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "s1", "s2" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } public void testStructureByReferenceField() { StructureWithPointers s = new StructureWithPointers(); - assertEquals("Wrong size for structure with structure references", - Pointer.SIZE * 2, s.size()); - + assertEquals("Wrong size for structure with structure references", Pointer.SIZE * 2, s.size()); assertNull("Initial refs should be null", s.s1); } public void testRegenerateStructureByReferenceField() { StructureWithPointers s = new StructureWithPointers(); - PublicTestStructure.ByReference inner = - new PublicTestStructure.ByReference(); + PublicTestStructure.ByReference inner = new PublicTestStructure.ByReference(); PublicTestStructure.allocations = 0; s.s1 = inner; s.write(); @@ -951,8 +1028,9 @@ public TestPointer p2 = new TestPointer() { { setPointer(new Memory(256)); } }; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "p", "p2" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("p", "p2"); } } TestStructure s = new TestStructure(); @@ -970,8 +1048,9 @@ class TestStructure extends Structure { public String s; public WString ws; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "s", "ws" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("s", "ws"); } } TestStructure s = new TestStructure(); @@ -993,29 +1072,34 @@ // Ensure string cacheing doesn't interfere with wrapped structure writes. public static class StructureFromPointer extends Structure { + public static final List FIELDS = createFieldsOrder("s", "ws"); public String s; public WString ws; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "s", "ws" }); - } public StructureFromPointer(Pointer p) { super(p); read(); } public StructureFromPointer() { + super(); + } + @Override + protected List getFieldOrder() { + return FIELDS; } } public void testInitializeStructureFieldWithStrings() { class ContainingStructure extends Structure { public StructureFromPointer inner; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "inner" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("inner"); } } - final String VALUE = getName() + UNICODE; - final WString WVALUE = new WString(VALUE); StructureFromPointer o = new StructureFromPointer(); + Charset charset = Charset.forName(o.getStringEncoding()); + final String VALUE = getName() + charset.decode(charset.encode(UNICODE)); + final WString WVALUE = new WString(VALUE); o.s = VALUE; o.ws = WVALUE; o.write(); @@ -1058,8 +1142,9 @@ public void testStructureByReferenceArrayField() { class TestStructure extends Structure { public PublicTestStructure.ByReference[] array = new PublicTestStructure.ByReference[2]; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "array" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("array"); } } TestStructure s = new TestStructure(); @@ -1088,8 +1173,9 @@ public void testAutoReadWriteStructureByReferenceArrayField() { class TestStructure extends Structure { public PublicTestStructure.ByReference field; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "field" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("field"); } } TestStructure s = new TestStructure(); @@ -1108,36 +1194,40 @@ VALUE*2, array[1].x); } - static class NestedTypeInfoStructure extends Structure { + public static class NestedTypeInfoStructure extends Structure { + public static final List FIELDS = createFieldsOrder("inner", "dummy"); public static class Inner extends Structure { + public static final List FIELDS = createFieldsOrder("dummy"); public int dummy; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "dummy" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } public Inner inner; public int dummy; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "inner", "dummy" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } public static class size_t extends IntegerType { + private static final long serialVersionUID = 1L; public size_t() { this(0); } public size_t(long value) { super(Native.POINTER_SIZE, value); } } /** Same structure as the internal representation, to be initialized from * the internal FFIType native data. */ - class TestFFIType extends Structure { + public static class TestFFIType extends Structure { + public static final List FIELDS = createFieldsOrder("size", "alignment", "type", "elements"); // NOTE: this field is not normally initialized by libffi // We force initialize by calling initialize_ffi_type public size_t size; public short alignment; public short type; public Pointer elements; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "size", "alignment", "type", "elements" }); - } + public TestFFIType(Pointer p) { super(p); read(); @@ -1149,6 +1239,10 @@ read(); assertEquals("Test FFIType size improperly initialized: " + TestFFIType.this, size, TestFFIType.this.size.intValue()); } + @Override + protected List getFieldOrder() { + return FIELDS; + } } public void testNestedStructureTypeInfo() { NestedTypeInfoStructure s = new NestedTypeInfoStructure(); @@ -1161,7 +1255,7 @@ assertEquals("Wrong type information for 'inner' field", inner, els.getPointer(0)); assertEquals("Wrong type information for integer field", - Structure.getTypeInfo(new Integer(0)), + Structure.getTypeInfo(Integer.valueOf(0)), els.getPointer(Pointer.SIZE)); assertNull("Type element list should be null-terminated", els.getPointer(Pointer.SIZE*2)); @@ -1170,8 +1264,9 @@ public void testInnerArrayTypeInfo() { class TestStructure extends Structure { public int[] inner = new int[5]; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "inner" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("inner"); } } Structure s = new TestStructure(); @@ -1195,8 +1290,9 @@ class TestStructure extends Structure { public int intField; public PublicTestStructure inner; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "intField", "inner" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("intField", "inner"); } } TestStructure s = new TestStructure(); @@ -1226,8 +1322,9 @@ public void testNativeMappedWrite() { class TestStructure extends Structure { public ByteByReference ref; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "ref" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("ref"); } } TestStructure s = new TestStructure(); @@ -1243,8 +1340,9 @@ public void testNativeMappedRead() { class TestStructure extends Structure { public ByteByReference ref; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "ref" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("ref"); } } TestStructure s = new TestStructure(); @@ -1262,9 +1360,11 @@ } public static class ROStructure extends Structure { + public static final List FIELDS = createFieldsOrder("field"); public final int field; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "field" }); + @Override + protected List getFieldOrder() { + return FIELDS; } { // Initialize in ctor to avoid compiler replacing @@ -1313,8 +1413,9 @@ final int SIZE = 24; class TestStructure extends Structure { public NativeLong[] longs = new NativeLong[SIZE]; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "longs" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("longs"); } } TestStructure s = new TestStructure(); @@ -1349,8 +1450,9 @@ { setAlignType(ALIGN_NONE); } public NativeLong nl = INITIAL; public NativeLong uninitialized; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "nl", "uninitialized" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("nl", "uninitialized"); } } TestStructure ts = new TestStructure(); @@ -1372,15 +1474,16 @@ public void testThrowErrorOnMissingFieldOrderOnDerivedStructure() { class TestStructure extends Structure { public int f1, f2; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "f1", "f2" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("f1", "f2"); } } - class TestStructure2 extends TestStructure { + class NoFieldOrder extends TestStructure { public int f3; } try { - new TestStructure2(); + new NoFieldOrder(); fail("Expected an error when structure fails to provide field order"); } catch(Error e) { @@ -1390,8 +1493,9 @@ public void testThrowErrorOnIncorrectFieldOrderNameMismatch() { class TestStructure extends Structure { public int f1, f2; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "F1", "F2" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("F1", "F2"); } } try { @@ -1405,8 +1509,9 @@ public void testThrowErrorOnIncorrectFieldOrderCount() { class TestStructure extends Structure { public int f1, f2; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "f1", "f2", "f3" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("f1", "f2", "f3"); } } try { @@ -1414,30 +1519,48 @@ fail("Expected an error when creating a structure with wrong number of fiels in getFieldOrder()"); } catch(Error e) { + // expected - ignored } } - class XTestStructure extends Structure { - public int first = 1; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "first" }); } - } - class XTestStructureSub extends XTestStructure { - public int second = 2; - protected List getFieldOrder() { - List list = new ArrayList(super.getFieldOrder()); - list.addAll(Arrays.asList(new String[] { "second" })); - return list; - } + public static class XTestStructure extends Structure { + public static final List FIELDS = createFieldsOrder("first"); + public int first = 1; + @Override + protected List getFieldOrder() { + return FIELDS; + } + } + + public static class XTestStructureSub extends XTestStructure { + public static final List EXTRA_FIELDS = createFieldsOrder("second"); + private static final AtomicReference> fieldsHolder = new AtomicReference>(null); + private static List resolveEffectiveFields(List baseFields) { + List fields; + synchronized (fieldsHolder) { + fields = fieldsHolder.get(); + if (fields == null) { + fields = createFieldsOrder(baseFields, EXTRA_FIELDS); + fieldsHolder.set(fields); + } + } + + return fields; + } + public int second = 2; + + @Override + protected List getFieldOrder() { + return resolveEffectiveFields(super.getFieldOrder()); + } } + public void testInheritedStructureFieldOrder() { XTestStructureSub s = new XTestStructureSub(); assertEquals("Wrong size", 8, s.size()); s.write(); - assertEquals("Wrong first field: " + s, - s.first, s.getPointer().getInt(0)); - assertEquals("Wrong second field: " + s, - s.second, s.getPointer().getInt(4)); + assertEquals("Wrong first field: " + s, s.first, s.getPointer().getInt(0)); + assertEquals("Wrong second field: " + s, s.second, s.getPointer().getInt(4)); } public void testVariedStructureFieldOrder() { @@ -1447,45 +1570,37 @@ public int one = 1; public int three = 3; public int two = 2; - protected List getFieldOrder() { + @Override + protected List getFieldOrder() { return Arrays.asList(ORDER); } } class DerivedTestStructure extends TestStructure { public int five = 5; public int four = 4; - protected List getFieldOrder() { - List list = new ArrayList(super.getFieldOrder()); - list.addAll(Arrays.asList(new String[] { "four", "five" })); + @Override + protected List getFieldOrder() { + List list = new ArrayList(super.getFieldOrder()); + list.addAll(Arrays.asList("four", "five")); return list; } } TestStructure s = new TestStructure(); - assertEquals("Wrong field order", - Arrays.asList(ORDER), s.getFieldOrder()); + assertEquals("Wrong field order", Arrays.asList(ORDER), s.getFieldOrder()); s.write(); - assertEquals("Wrong first field: " + s, - s.one, s.getPointer().getInt(0)); - assertEquals("Wrong second field: " + s, - s.two, s.getPointer().getInt(4)); - assertEquals("Wrong third field: " + s, - s.three, s.getPointer().getInt(8)); + assertEquals("Wrong first field: " + s, s.one, s.getPointer().getInt(0)); + assertEquals("Wrong second field: " + s, s.two, s.getPointer().getInt(4)); + assertEquals("Wrong third field: " + s, s.three, s.getPointer().getInt(8)); DerivedTestStructure s2 = new DerivedTestStructure(); - assertEquals("Wrong field order", - Arrays.asList(ORDER2), s2.getFieldOrder()); + assertEquals("Wrong field order", Arrays.asList(ORDER2), s2.getFieldOrder()); s2.write(); - assertEquals("Wrong first field: " + s2, - s2.one, s2.getPointer().getInt(0)); - assertEquals("Wrong second field: " + s2, - s2.two, s2.getPointer().getInt(4)); - assertEquals("Wrong third field: " + s2, - s2.three, s2.getPointer().getInt(8)); - assertEquals("Wrong derived field (1): " + s2, - s2.four, s2.getPointer().getInt(12)); - assertEquals("Wrong derived field (2): " + s2, - s2.five, s2.getPointer().getInt(16)); + assertEquals("Wrong first field: " + s2, s2.one, s2.getPointer().getInt(0)); + assertEquals("Wrong second field: " + s2, s2.two, s2.getPointer().getInt(4)); + assertEquals("Wrong third field: " + s2, s2.three, s2.getPointer().getInt(8)); + assertEquals("Wrong derived field (1): " + s2, s2.four, s2.getPointer().getInt(12)); + assertEquals("Wrong derived field (2): " + s2, s2.five, s2.getPointer().getInt(16)); } public void testCustomTypeMapper() { @@ -1493,12 +1608,15 @@ final DefaultTypeMapper mapper = new DefaultTypeMapper() { { addTypeConverter(TestField.class, new TypeConverter() { + @Override public Object fromNative(Object value, FromNativeContext context) { return new TestField(); } - public Class nativeType() { + @Override + public Class nativeType() { return String.class; } + @Override public Object toNative(Object value, ToNativeContext ctx) { return value == null ? null : value.toString(); } @@ -1510,8 +1628,9 @@ public TestStructure() { super(mapper); } - protected List getFieldOrder() { - return Arrays.asList(new String[] { "field" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("field"); } } Structure s = new TestStructure(); @@ -1522,8 +1641,9 @@ class TestStructure extends Structure { public Boolean zfield; public Integer field; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "zfield", "field" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("zfield", "field"); } } TestStructure s = new TestStructure(); @@ -1537,16 +1657,18 @@ public int first; public int[] second = new int[4]; public Pointer[] third = new Pointer[4]; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "first", "second", "third" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("first", "second", "third"); } } class TestStructure extends Structure { public int first; public int[] second = new int[4]; public Pointer[] third = new Pointer[4]; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "first", "second", "third" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("first", "second", "third"); } public TestStructure() { } public TestStructure(Pointer p) { super(p); } @@ -1571,8 +1693,9 @@ public void testStructureHashCodeMatchesWhenEqual() { class TestStructure extends Structure { public int first; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "first" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("first"); } } TestStructure s1 = new TestStructure(); @@ -1580,12 +1703,10 @@ assertFalse("hashCode should be different for two different structures", s1.hashCode() == s2.hashCode()); s2.useMemory(s1.getPointer()); - assertEquals("hashCode should match when structures have same pointer", - s1.hashCode(), s2.hashCode()); + assertEquals("hashCode should match when structures have same pointer", s1.hashCode(), s2.hashCode()); s2.useMemory(s1.getPointer()); - assertEquals("hashCode should match when structures have same pointer", - s1.hashCode(), s2.hashCode()); + assertEquals("hashCode should match when structures have same pointer", s1.hashCode(), s2.hashCode()); } public void testRecursiveWrite() { @@ -1594,8 +1715,9 @@ public TestStructureByRef() { } public int unique; public TestStructureByRef s; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "unique", "s" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("unique", "s"); } } TestStructureByRef s = new TestStructureByRef(); @@ -1605,30 +1727,26 @@ s.s.unique = 2; s.write(); - assertEquals("Structure field contents not written", - 1, s.getPointer().getInt(0)); - assertEquals("ByReference structure field contents not written", - 2, s.s.getPointer().getInt(0)); + assertEquals("Structure field contents not written", 1, s.getPointer().getInt(0)); + assertEquals("ByReference structure field contents not written", 2, s.s.getPointer().getInt(0)); s.s.unique = 0; Structure value = s.s; s.read(); assertEquals("ByReference structure field not preserved", value, s.s); - - assertEquals("ByReference structure field contents not read", - 2, s.s.unique); - - assertTrue("Temporary storage should be cleared", - s.busy().isEmpty()); + assertEquals("ByReference structure field contents not read", 2, s.s.unique); + assertTrue("Temporary storage should be cleared", Structure.busy().isEmpty()); } public static class CyclicTestStructure extends Structure { public static class ByReference extends CyclicTestStructure implements Structure.ByReference {} + public static final List FIELDS = createFieldsOrder("next"); public CyclicTestStructure(Pointer p) { super(p); } public CyclicTestStructure() { } public CyclicTestStructure.ByReference next; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "next" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } public void testCyclicRead() { @@ -1644,21 +1762,21 @@ value = s.next; s.next.next = null; s.read(); - assertSame("ByReference structure field should reuse existing value", - value, s.next); - assertSame("Nested ByReference structure field should reuse existing value", - value, s.next.next); + assertSame("ByReference structure field should reuse existing value", value, s.next); + assertSame("Nested ByReference structure field should reuse existing value", value, s.next.next); } public void testAvoidMemoryAllocationInPointerCTOR() { class TestStructure extends Structure { public int field; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "field" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("field"); } public TestStructure(Pointer p) { super(p); } + @Override protected Memory autoAllocate(int size) { fail("Memory should not be auto-allocated"); return null; @@ -1672,8 +1790,9 @@ class TestStructure extends Structure { public int intField; public byte[] arrayField = new byte[256]; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "intField", "arrayField" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("intField", "arrayField"); } public TestStructure(Pointer p) { super(p); @@ -1703,6 +1822,7 @@ public static class TestByReferenceArrayField extends Structure { + public static final List FIELDS = createFieldsOrder("value1", "array", "value2"); public TestByReferenceArrayField() { } public TestByReferenceArrayField(Pointer m) { super(m); @@ -1711,8 +1831,9 @@ public int value1; public ByReference[] array = new ByReference[13]; public int value2; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "value1", "array", "value2" }); + @Override + protected List getFieldOrder() { + return FIELDS; } public static class ByReference extends TestByReferenceArrayField implements Structure.ByReference { } @@ -1738,8 +1859,9 @@ public void testEquals() { class TestStructure extends Structure { public int field; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "field" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("field"); } public TestStructure() { } public TestStructure(Pointer p) { super(p); read(); } @@ -1755,8 +1877,9 @@ public void testStructureLayoutCacheing() { class TestStructure extends Structure { public int field; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "field" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("field"); } } Structure ts = new TestStructure(); ts.ensureAllocated(); @@ -1768,8 +1891,9 @@ public void testStructureLayoutVariableNoCache() { class TestStructure extends Structure { public byte[] variable; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "variable" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("variable"); } public TestStructure(int size) { this.variable = new byte[size]; @@ -1787,12 +1911,15 @@ class TestTypeMapper extends DefaultTypeMapper { { TypeConverter tc = new TypeConverter() { - public Class nativeType() { return int.class; } + @Override + public Class nativeType() { return int.class; } + @Override public Object fromNative(Object nativeValue, FromNativeContext c) { - return new Boolean(nativeValue.equals(new Integer(0))); + return Boolean.valueOf(nativeValue.equals(Integer.valueOf(0))); } + @Override public Object toNative(Object value, ToNativeContext c) { - return new Integer(Boolean.TRUE.equals(value) ? -1 : 0); + return Integer.valueOf(Boolean.TRUE.equals(value) ? -1 : 0); } }; addTypeConverter(boolean.class, tc); @@ -1802,8 +1929,9 @@ final TestTypeMapper m = new TestTypeMapper(); class TestStructure extends Structure { public boolean field; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "field" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("field"); } public TestStructure() { super(m); @@ -1823,8 +1951,9 @@ class TestStructure extends Structure { public byte first; public int second; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "first", "second" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("first", "second"); } public TestStructure() { setAlignType(ALIGN_NONE); @@ -1848,29 +1977,35 @@ public void testFFITypeCalculationWithTypeMappedFields() { final TypeMapper mapper = new TypeMapper() { - public FromNativeConverter getFromNativeConverter(Class cls) { + @Override + public FromNativeConverter getFromNativeConverter(Class cls) { if (Boolean.class.equals(cls) || boolean.class.equals(cls)) { return new FromNativeConverter() { - public Class nativeType() { + @Override + public Class nativeType() { return byte.class; } + @Override public Object fromNative(Object nativeValue, FromNativeContext context) { - return nativeValue.equals(new Byte((byte)0)) + return nativeValue.equals(Byte.valueOf((byte)0)) ? Boolean.FALSE : Boolean.TRUE; } }; } return null; } - public ToNativeConverter getToNativeConverter(Class javaType) { + @Override + public ToNativeConverter getToNativeConverter(Class javaType) { if (Boolean.class.equals(javaType) || boolean.class.equals(javaType)) { return new ToNativeConverter() { + @Override public Object toNative(Object value, ToNativeContext context) { - return new Byte(Boolean.TRUE.equals(value) ? (byte)1 : (byte)0); + return Byte.valueOf(Boolean.TRUE.equals(value) ? (byte)1 : (byte)0); } - public Class nativeType() { + @Override + public Class nativeType() { return byte.class; } }; @@ -1886,8 +2021,9 @@ public TestStructure() { super(mapper); } - protected List getFieldOrder() { - return Arrays.asList(new String[] { "b", "s", "p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("b", "s", "p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7"); } } Structure s = new TestStructure(); @@ -1901,8 +2037,9 @@ public void testDefaultStringEncoding() { class TestStructure extends Structure { public String field; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "field" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("field"); } } TestStructure s = new TestStructure(); @@ -1914,8 +2051,9 @@ public void testStringFieldEncoding() throws Exception { class TestStructure extends Structure { public String field; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "field" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("field"); } } TestStructure s = new TestStructure(); @@ -1939,18 +2077,19 @@ s.read(); assertEquals("String not decoded properly on read", VALUE, s.field); } - + public void testThreadLocalSetReleasesReferences() { class TestStructure extends Structure { public String field; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "field" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("field"); } } - + TestStructure ts1 = new TestStructure(); TestStructure ts2 = new TestStructure(); - + StructureSet structureSet = (StructureSet) Structure.busy(); structureSet.add(ts1); structureSet.add(ts2); diff -Nru libjna-java-4.2.2/test/com/sun/jna/TypeMapperTest.java libjna-java-4.4.0/test/com/sun/jna/TypeMapperTest.java --- libjna-java-4.2.2/test/com/sun/jna/TypeMapperTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/TypeMapperTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,23 +1,32 @@ /* Copyright (c) 2007 Wayne Meissner, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

        - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.Arrays; -import java.util.HashMap; +import java.util.Collections; import java.util.List; -import java.util.Map; - import junit.framework.TestCase; //@SuppressWarnings("unused") @@ -35,116 +44,106 @@ public void testBooleanToIntArgumentConversion() { final int MAGIC = 0xABEDCF23; - Map options = new HashMap(); DefaultTypeMapper mapper = new DefaultTypeMapper(); mapper.addToNativeConverter(Boolean.class, new ToNativeConverter() { + @Override public Object toNative(Object arg, ToNativeContext ctx) { - return new Integer(Boolean.TRUE.equals(arg) ? MAGIC : 0); + return Integer.valueOf(Boolean.TRUE.equals(arg) ? MAGIC : 0); } - public Class nativeType() { + @Override + public Class nativeType() { return Integer.class; } }); - options.put(Library.OPTION_TYPE_MAPPER, mapper); - TestLibrary lib = (TestLibrary) - Native.loadLibrary("testlib", TestLibrary.class, options); - assertEquals("Failed to convert Boolean argument to Int", MAGIC, - lib.returnInt32Argument(true)); + TestLibrary lib = Native.loadLibrary("testlib", TestLibrary.class, Collections.singletonMap(Library.OPTION_TYPE_MAPPER, mapper)); + assertEquals("Failed to convert Boolean argument to Int", MAGIC, lib.returnInt32Argument(true)); } public void testStringToIntArgumentConversion() { DefaultTypeMapper mapper = new DefaultTypeMapper(); mapper.addToNativeConverter(String.class, new ToNativeConverter() { + @Override public Object toNative(Object arg, ToNativeContext ctx) { return Integer.valueOf((String) arg, 16); } - public Class nativeType() { + @Override + public Class nativeType() { return Integer.class; } }); - Map options = new HashMap(); - options.put(Library.OPTION_TYPE_MAPPER, mapper); final int MAGIC = 0x7BEDCF23; - TestLibrary lib = (TestLibrary) - Native.loadLibrary("testlib", TestLibrary.class, options); + TestLibrary lib = Native.loadLibrary("testlib", TestLibrary.class, Collections.singletonMap(Library.OPTION_TYPE_MAPPER, mapper)); assertEquals("Failed to convert String argument to Int", MAGIC, lib.returnInt32Argument(Integer.toHexString(MAGIC))); } public void testStringToWStringArgumentConversion() { DefaultTypeMapper mapper = new DefaultTypeMapper(); mapper.addToNativeConverter(String.class, new ToNativeConverter() { + @Override public Object toNative(Object arg, ToNativeContext ctx) { return new WString(arg.toString()); } - public Class nativeType() { + @Override + public Class nativeType() { return WString.class; } }); - Map options = new HashMap(); - options.put(Library.OPTION_TYPE_MAPPER, mapper); final String MAGIC = "magic" + UNICODE; - TestLibrary lib = (TestLibrary) - Native.loadLibrary("testlib", TestLibrary.class, options); + TestLibrary lib = Native.loadLibrary("testlib", TestLibrary.class, Collections.singletonMap(Library.OPTION_TYPE_MAPPER, mapper)); assertEquals("Failed to convert String argument to WString", new WString(MAGIC), lib.returnWStringArgument(MAGIC)); } public void testCharSequenceToIntArgumentConversion() { DefaultTypeMapper mapper = new DefaultTypeMapper(); mapper.addToNativeConverter(CharSequence.class, new ToNativeConverter() { + @Override public Object toNative(Object arg, ToNativeContext ctx) { return Integer.valueOf(((CharSequence)arg).toString(), 16); } - public Class nativeType() { + @Override + public Class nativeType() { return Integer.class; } }); - Map options = new HashMap(); - options.put(Library.OPTION_TYPE_MAPPER, mapper); - final int MAGIC = 0x7BEDCF23; - TestLibrary lib = (TestLibrary) - Native.loadLibrary("testlib", TestLibrary.class, options); - assertEquals("Failed to convert String argument to Int", MAGIC, - lib.returnInt32Argument(Integer.toHexString(MAGIC))); + TestLibrary lib = Native.loadLibrary("testlib", TestLibrary.class, Collections.singletonMap(Library.OPTION_TYPE_MAPPER, mapper)); + assertEquals("Failed to convert String argument to Int", MAGIC, lib.returnInt32Argument(Integer.toHexString(MAGIC))); } public void testNumberToIntArgumentConversion() { DefaultTypeMapper mapper = new DefaultTypeMapper(); mapper.addToNativeConverter(Double.class, new ToNativeConverter() { + @Override public Object toNative(Object arg, ToNativeContext ctx) { - return new Integer(((Double)arg).intValue()); + return Integer.valueOf(((Double)arg).intValue()); } - public Class nativeType() { + @Override + public Class nativeType() { return Integer.class; } }); - Map options = new HashMap(); - options.put(Library.OPTION_TYPE_MAPPER, mapper); - + final int MAGIC = 0x7BEDCF23; - TestLibrary lib = (TestLibrary) - Native.loadLibrary("testlib", TestLibrary.class, options); + TestLibrary lib = Native.loadLibrary("testlib", TestLibrary.class, Collections.singletonMap(Library.OPTION_TYPE_MAPPER, mapper)); assertEquals("Failed to convert Double argument to Int", MAGIC, - lib.returnInt32Argument(new Double(MAGIC))); + lib.returnInt32Argument(Double.valueOf(MAGIC))); } public void testWStringToStringResultConversion() throws Exception { final String MAGIC = "magic" + UNICODE; DefaultTypeMapper mapper = new DefaultTypeMapper(); mapper.addFromNativeConverter(String.class, new FromNativeConverter() { + @Override public Object fromNative(Object value, FromNativeContext ctx) { if (value == null) { return null; } return value.toString(); } - public Class nativeType() { + @Override + public Class nativeType() { return WString.class; } }); - Map options = new HashMap(); - options.put(Library.OPTION_TYPE_MAPPER, mapper); - TestLibrary lib = (TestLibrary) - Native.loadLibrary("testlib", TestLibrary.class, options); - assertEquals("Failed to convert WString result to String", MAGIC, - lib.returnWStringArgument(new WString(MAGIC))); + TestLibrary lib = Native.loadLibrary("testlib", TestLibrary.class, Collections.singletonMap(Library.OPTION_TYPE_MAPPER, mapper)); + assertEquals("Failed to convert WString result to String", MAGIC, lib.returnWStringArgument(new WString(MAGIC))); } public static interface BooleanTestLibrary extends Library { @@ -152,73 +151,74 @@ } public void testIntegerToBooleanResultConversion() throws Exception { final int MAGIC = 0xABEDCF23; - Map options = new HashMap(); DefaultTypeMapper mapper = new DefaultTypeMapper(); mapper.addToNativeConverter(Boolean.class, new ToNativeConverter() { + @Override public Object toNative(Object value, ToNativeContext ctx) { - return new Integer(Boolean.TRUE.equals(value) ? MAGIC : 0); + return Integer.valueOf(Boolean.TRUE.equals(value) ? MAGIC : 0); } - public Class nativeType() { + @Override + public Class nativeType() { return Integer.class; } }); mapper.addFromNativeConverter(Boolean.class, new FromNativeConverter() { + @Override public Object fromNative(Object value, FromNativeContext context) { return Boolean.valueOf(((Integer) value).intValue() == MAGIC); } - public Class nativeType() { + @Override + public Class nativeType() { return Integer.class; } }); - options.put(Library.OPTION_TYPE_MAPPER, mapper); - BooleanTestLibrary lib = (BooleanTestLibrary) - Native.loadLibrary("testlib", BooleanTestLibrary.class, options); - assertEquals("Failed to convert integer return to boolean TRUE", true, - lib.returnInt32Argument(true)); - assertEquals("Failed to convert integer return to boolean FALSE", false, - lib.returnInt32Argument(false)); + BooleanTestLibrary lib = Native.loadLibrary("testlib", BooleanTestLibrary.class, Collections.singletonMap(Library.OPTION_TYPE_MAPPER, mapper)); + assertEquals("Failed to convert integer return to boolean TRUE", true, lib.returnInt32Argument(true)); + assertEquals("Failed to convert integer return to boolean FALSE", false, lib.returnInt32Argument(false)); } + public static interface StructureTestLibrary extends Library { public static class TestStructure extends Structure { public TestStructure(TypeMapper mapper) { super(mapper); } public boolean data; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "data" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("data"); } } } public void testStructureConversion() throws Exception { DefaultTypeMapper mapper = new DefaultTypeMapper(); TypeConverter converter = new TypeConverter() { + @Override public Object toNative(Object value, ToNativeContext ctx) { - return new Integer(Boolean.TRUE.equals(value) ? 1 : 0); + return Integer.valueOf(Boolean.TRUE.equals(value) ? 1 : 0); } + @Override public Object fromNative(Object value, FromNativeContext context) { - return new Boolean(((Integer)value).intValue() == 1); + return Boolean.valueOf(((Integer)value).intValue() == 1); } - public Class nativeType() { + @Override + public Class nativeType() { return Integer.class; } }; mapper.addTypeConverter(Boolean.class, converter); - Map options = new HashMap(); - options.put(Library.OPTION_TYPE_MAPPER, mapper); - StructureTestLibrary lib = (StructureTestLibrary) - Native.loadLibrary("testlib", StructureTestLibrary.class, options); + Native.loadLibrary("testlib", StructureTestLibrary.class, Collections.singletonMap(Library.OPTION_TYPE_MAPPER, mapper)); StructureTestLibrary.TestStructure s = new StructureTestLibrary.TestStructure(mapper); assertEquals("Wrong native size", 4, s.size()); - + s.data = true; s.write(); assertEquals("Wrong value written", 1, s.getPointer().getInt(0)); - + s.getPointer().setInt(0, 0); s.read(); assertFalse("Wrong value read", s.data); } - + public static enum Enumeration { STATUS_0(0), STATUS_1(1), STATUS_ERROR(-1); private final int code; @@ -238,24 +238,24 @@ public void testEnumConversion() throws Exception { DefaultTypeMapper mapper = new DefaultTypeMapper(); TypeConverter converter = new TypeConverter() { + @Override public Object toNative(Object value, ToNativeContext ctx) { - return new Integer(((Enumeration)value).getCode()); + return Integer.valueOf(((Enumeration)value).getCode()); } + @Override public Object fromNative(Object value, FromNativeContext context) { return Enumeration.fromCode(((Integer)value).intValue()); } - public Class nativeType() { + @Override + public Class nativeType() { return Integer.class; } }; mapper.addTypeConverter(Enumeration.class, converter); - Map options = new HashMap(); - options.put(Library.OPTION_TYPE_MAPPER, mapper); - EnumerationTestLibrary lib = (EnumerationTestLibrary) - Native.loadLibrary("testlib", EnumerationTestLibrary.class, options); + EnumerationTestLibrary lib = Native.loadLibrary("testlib", EnumerationTestLibrary.class, Collections.singletonMap(Library.OPTION_TYPE_MAPPER, mapper)); assertEquals("Enumeration improperly converted", Enumeration.STATUS_1, lib.returnInt32Argument(Enumeration.STATUS_1)); } - + public static void main(String[] args) { junit.textui.TestRunner.run(TypeMapperTest.class); } diff -Nru libjna-java-4.2.2/test/com/sun/jna/UnionTest.java libjna-java-4.4.0/test/com/sun/jna/UnionTest.java --- libjna-java-4.2.2/test/com/sun/jna/UnionTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/UnionTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,18 +1,28 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.Arrays; import java.util.List; import junit.framework.TestCase; @@ -21,24 +31,30 @@ public class UnionTest extends TestCase { public static class TestStructure extends Structure { + public static final List FIELDS = createFieldsOrder("value"); public String value; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "value" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } public static class BigTestStructure extends Structure { + public static final List FIELDS = createFieldsOrder("field1", "field2"); public long field1; public long field2; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "field1", "field2" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } public static class IntStructure extends Structure { + public static final List FIELDS = createFieldsOrder("value"); public int value; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "value" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } @@ -132,6 +148,7 @@ // write an instance of an interface u = new StructUnion(); Func1 func1 = new Func1() { + @Override public void callback() { System.out.println("hi"); } diff -Nru libjna-java-4.2.2/test/com/sun/jna/VarArgsCheckerTest.java libjna-java-4.4.0/test/com/sun/jna/VarArgsCheckerTest.java --- libjna-java-4.2.2/test/com/sun/jna/VarArgsCheckerTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/VarArgsCheckerTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,4 +1,26 @@ -package com.sun.jna; +/* + * 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.lang.reflect.Method; @@ -7,28 +29,59 @@ public class VarArgsCheckerTest extends TestCase { public void testCreation() throws Exception { - final VarArgsChecker sut = VarArgsChecker.create(); - assertNotNull(sut); + final VarArgsChecker checker = VarArgsChecker.create(); + assertNotNull(checker); } public void testNoVarArgs() throws Exception { - final VarArgsChecker sut = VarArgsChecker.create(); - final Method toCheckForVarArgs = VarArgsCheckerTest.class.getMethod("testNoVarArgs", new Class[0]); - final boolean res = sut.isVarArgs(toCheckForVarArgs); + final VarArgsChecker checker = VarArgsChecker.create(); + final Method method = VarArgsCheckerTest.class.getMethod("testNoVarArgs", new Class[0]); + final boolean res = checker.isVarArgs(method); // no matter if JVM 1.4 or 1.5+, the result should always be false - assertFalse(res); + assertFalse("Method should not be detected as varargs", res); + assertEquals("Non-varargs should return fixed args of zero", 0, checker.fixedArgs(method)); } public void testVarArgsExist() throws Exception { - final VarArgsChecker sut = VarArgsChecker.create(); - final Method toCheckForVarArgs = VarArgsCheckerTest.class.getMethod("methodWithVarArgs", new Class[]{String[].class}); - final boolean res = sut.isVarArgs(toCheckForVarArgs); + final VarArgsChecker checker = VarArgsChecker.create(); + final Method method = VarArgsCheckerTest.class.getMethod("methodWithVarArgs", new Class[]{String[].class}); + final boolean res = checker.isVarArgs(method); // this test has to run with Java 1.5+, because this has a method with // varargs. So the result has to be true. - assertTrue(res); + assertTrue("Method should be detected as varargs", res); + } + + public void testFixedArgsOne() throws Exception { + final VarArgsChecker checker = VarArgsChecker.create(); + final Method method = VarArgsCheckerTest.class.getMethod("methodWithOneFixedArg", new Class[]{String.class, Object[].class}); + final int res = checker.fixedArgs(method); + // this test has to run with Java 1.5+, because this has a method with + // varargs. So the result has to be true. + assertEquals("Wrong number of fixed args", 1, res); + } + + public void testFixedArgsTwo() throws Exception { + final VarArgsChecker checker = VarArgsChecker.create(); + final Method method = VarArgsCheckerTest.class.getMethod("methodWithTwoFixedArgs", new Class[]{String.class, String.class, Object[].class}); + final int res = checker.fixedArgs(method); + // this test has to run with Java 1.5+, because this has a method with + // varargs. So the result has to be true. + assertEquals("Wrong number of fixed args", 2, res); } public void methodWithVarArgs(String... args) { - System.out.println(); + // nothing to do + } + + public void methodWithOneFixedArg(String fmt, Object... args) { + // nothing to do + } + + public void methodWithTwoFixedArgs(String fmt, String fmt2, Object... args) { + // nothing to do + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(VarArgsCheckerTest.class); } } diff -Nru libjna-java-4.2.2/test/com/sun/jna/VarArgsTest.java libjna-java-4.4.0/test/com/sun/jna/VarArgsTest.java --- libjna-java-4.2.2/test/com/sun/jna/VarArgsTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/VarArgsTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Wayne Meissner, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

        - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; @@ -24,62 +35,84 @@ public static interface TestLibrary extends Library { public static class TestStructure extends Structure { public int magic = 0; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "magic" }); + @Override + protected List getFieldOrder() { + return Arrays.asList("magic"); } } - public int addInt32VarArgs(String fmt, Number... args); + public int addVarArgs(String fmt, Number... args); public String returnStringVarArgs(String fmt, Object... args); public void modifyStructureVarArgs(String fmt, Object arg1, Object... args); + public String returnStringVarArgs2(String... args); } TestLibrary lib; + @Override protected void setUp() { - lib = (TestLibrary)Native.loadLibrary("testlib", TestLibrary.class); + lib = Native.loadLibrary("testlib", TestLibrary.class); } + @Override protected void tearDown() { lib = null; - } + } public void testIntVarArgs() { int arg1 = 1; int arg2 = 2; - assertEquals("VarArgs not added correctly", arg1 + arg2, - lib.addInt32VarArgs("dd", new Integer(arg1), new Integer(arg2))); + assertEquals("32-bit integer varargs not added correctly", arg1 + arg2, + lib.addVarArgs("dd", Integer.valueOf(arg1), Integer.valueOf(arg2))); } public void testShortVarArgs() { short arg1 = 1; short arg2 = 2; - assertEquals("VarArgs not added correctly", arg1 + arg2, - lib.addInt32VarArgs("dd", new Short(arg1), new Short(arg2))); + assertEquals("16-bit integer varargs not added correctly", arg1 + arg2, + lib.addVarArgs("dd", Short.valueOf(arg1), Short.valueOf(arg2))); } public void testLongVarArgs() { short arg1 = 1; short arg2 = 2; - assertEquals("VarArgs not added correctly", arg1 + arg2, - lib.addInt32VarArgs("ll", new Long(arg1), new Long(arg2))); + assertEquals("64-bit integer varargs not added correctly", arg1 + arg2, + lib.addVarArgs("ll", Long.valueOf(arg1), Long.valueOf(arg2))); + } + public void testFloatVarArgs() { + float arg1 = 1; + float arg2 = 2; + assertEquals("float varargs not added correctly", (int)arg1 + (int)arg2, + lib.addVarArgs("ff", Float.valueOf(arg1), Float.valueOf(arg2))); + } + public void testDoubleVarArgs() { + double arg1 = 1; + double arg2 = 2; + assertEquals("double varargs not added correctly", (int)arg1 + (int)arg2, + lib.addVarArgs("gg", Double.valueOf(arg1), Double.valueOf(arg2))); } public void testStringVarArgs() { Object[] args = new Object[] { "Test" }; assertEquals("Did not return correct string", args[0], lib.returnStringVarArgs("", args)); } - + + public void testStringVarArgsFull() { + Object[] args = new Object[] { "Test" }; + assertEquals("Did not return correct string", args[0], + lib.returnStringVarArgs2("", "Test")); + } + public void testAppendNullToVarargs() { - Number[] args = new Number[] { new Integer(1) }; + Number[] args = new Number[] { Integer.valueOf(1) }; assertEquals("No trailing NULL was appended to varargs list", - 1, lib.addInt32VarArgs("dd", args)); + 1, lib.addVarArgs("dd", args)); } - + public void testModifyStructureInVarargs() { TestStructure arg1 = new TestStructure(); TestStructure[] varargs = new TestStructure[] { new TestStructure() }; lib.modifyStructureVarArgs("ss", arg1, varargs[0]); assertEquals("Structure memory not read in fixed arg w/varargs", - MAGIC32, arg1.magic); + MAGIC32, arg1.magic); assertEquals("Structure memory not read in varargs", - MAGIC32, varargs[0].magic); - + MAGIC32, varargs[0].magic); + } - + public static void main(String[] args) { junit.textui.TestRunner.run(VarArgsTest.class); } diff -Nru libjna-java-4.2.2/test/com/sun/jna/VMCrashProtectionTest.java libjna-java-4.4.0/test/com/sun/jna/VMCrashProtectionTest.java --- libjna-java-4.2.2/test/com/sun/jna/VMCrashProtectionTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/VMCrashProtectionTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; diff -Nru libjna-java-4.2.2/test/com/sun/jna/WebStartTest.java libjna-java-4.4.0/test/com/sun/jna/WebStartTest.java --- libjna-java-4.2.2/test/com/sun/jna/WebStartTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/WebStartTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2009-2012 Timothy Wall, 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * You can freely decide which license you want to apply to + * the project. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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; @@ -43,7 +54,7 @@ * Works under OSX, windows, and linux. */ public class WebStartTest extends TestCase implements Paths { - + // Provide a policy file for unsigned jars // Unfortunately this does not allow native libraries private static final String POLICY = @@ -51,7 +62,7 @@ + " permission java.security.AllPermission;\n" + "};"; - private static final String JNLP = + private static final String JNLP = "\n" + "\n" + " \n" @@ -135,91 +146,95 @@ String codebase = new File(dir, "jws").toURI().toURL().toString(); ServerSocket s = new ServerSocket(0); - s.setSoTimeout(SOCKET_TIMEOUT); - int port = s.getLocalPort(); + try { + s.setSoTimeout(SOCKET_TIMEOUT); + int port = s.getLocalPort(); - File jnlp = File.createTempFile(getName(), ".jnlp"); - String contents = JNLP.replace("{CLASS}", testClass); - contents = contents.replace("{METHOD}", testMethod); - contents = contents.replace("{CODEBASE}", codebase); - contents = contents.replace("{JNLP_FILE}", jnlp.toURI().toURL().toString()); - contents = contents.replace("{PORT}", String.valueOf(port)); - contents = contents.replace("{CLOVER}", - USING_CLOVER ? "" : ""); + File jnlp = File.createTempFile(getName(), ".jnlp"); + String contents = JNLP.replace("{CLASS}", testClass); + contents = contents.replace("{METHOD}", testMethod); + contents = contents.replace("{CODEBASE}", codebase); + contents = contents.replace("{JNLP_FILE}", jnlp.toURI().toURL().toString()); + contents = contents.replace("{PORT}", String.valueOf(port)); + contents = contents.replace("{CLOVER}", USING_CLOVER ? "" : ""); - try { - OutputStream os = new FileOutputStream(jnlp); - os.write(contents.getBytes()); - os.close(); - String path = findJWS(); - String[] cmd = { - path, - Platform.isWindows() ? "-J-Ddummy" : (Platform.is64Bit() ? "-J-d64" : "-J-d32"), - "-Xnosplash", - "-wait", - jnlp.toURI().toURL().toString(), - }; - final Process p = Runtime.getRuntime().exec(cmd); - final StringBuffer output = new StringBuffer(); - class SocketHandler extends Thread { - private InputStream is; - private StringBuffer sb; - public SocketHandler(Socket s, StringBuffer b) throws IOException { - this.is = s.getInputStream(); - this.sb = b; - } - public void run() { - byte[] buf = new byte[256]; - while (true) { - try { - int count = is.read(buf, 0, buf.length); - if (count == -1) break; - if (count == 0) { - try { sleep(1); } catch(InterruptedException e) { } + try { + OutputStream os = new FileOutputStream(jnlp); + os.write(contents.getBytes()); + os.close(); + String path = findJWS(); + String[] cmd = { + path, + Platform.isWindows() ? "-J-Ddummy" : (Platform.is64Bit() ? "-J-d64" : "-J-d32"), + "-Xnosplash", + "-wait", + jnlp.toURI().toURL().toString(), + }; + final Process p = Runtime.getRuntime().exec(cmd); + final StringBuffer output = new StringBuffer(); + class SocketHandler extends Thread { + private InputStream is; + private StringBuffer sb; + public SocketHandler(Socket s, StringBuffer b) throws IOException { + this.is = s.getInputStream(); + this.sb = b; + } + @Override + public void run() { + byte[] buf = new byte[256]; + while (true) { + try { + int count = is.read(buf, 0, buf.length); + if (count == -1) break; + if (count == 0) { + try { sleep(1); } catch(InterruptedException e) { } + } + else { + sb.append(new String(buf, 0, count)); + } } - else { - sb.append(new String(buf, 0, count)); + catch(IOException e) { + showMessage("read error: " + e.toString()); } } - catch(IOException e) { - showMessage("read error: " + e.toString()); - } + try { is.close(); } catch(IOException e) { } } - try { is.close(); } catch(IOException e) { } } - } - - Thread out = null; - try { - out = new SocketHandler(s.accept(), output); - out.start(); - } - catch(SocketTimeoutException e) { - try { - p.exitValue(); + + Thread out = null; + try { + out = new SocketHandler(s.accept(), output); + out.start(); } - catch(IllegalThreadStateException e2) { - p.destroy(); - throw new Error("JWS Timed out"); + catch(SocketTimeoutException e) { + try { + p.exitValue(); + } + catch(IllegalThreadStateException e2) { + p.destroy(); + throw new Error("JWS Timed out"); + } } - } - p.waitFor(); - if (out != null) { - out.join(); - } - - int code = p.exitValue(); - String error = output.toString(); - if (code != 0 || !"".equals(error)) { - if (code == 1 - || error.indexOf("AssertionFailedError") != -1) { - fail("JWS FAIL: " + error); + p.waitFor(); + if (out != null) { + out.join(); + } + + int code = p.exitValue(); + String error = output.toString(); + if (code != 0 || !"".equals(error)) { + if (code == 1 + || error.indexOf("AssertionFailedError") != -1) { + fail("JWS FAIL: " + error); + } + throw new Error("JWS ERROR: " + error); } - throw new Error("JWS ERROR: " + error); } - } - finally { - jnlp.delete(); + finally { + jnlp.delete(); + } + } finally { + s.close(); } } @@ -261,7 +276,7 @@ runTestUnderWebStart(getClass().getName(), getName()); } } - + public interface FolderInfo extends com.sun.jna.win32.StdCallLibrary { int MAX_PATH = 260; int SHGFP_TYPE_CURRENT = 0; @@ -276,7 +291,7 @@ 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 @@ -290,8 +305,7 @@ } // NOTE: win64 only includes javaws in the system path if (Platform.isWindows()) { - FolderInfo info = (FolderInfo) - Native.loadLibrary("shell32", FolderInfo.class); + FolderInfo info = Native.loadLibrary("shell32", FolderInfo.class); char[] buf = new char[FolderInfo.MAX_PATH]; //int result = info.SHGetFolderPathW(null, FolderInfo.CSIDL_WINDOWS, null, 0, buf); @@ -312,7 +326,7 @@ } // TODO: find some way of querying the current VM for the deployment - // properties path + // properties path private File findDeploymentProperties() { String path = System.getProperty("user.home"); File deployment; @@ -321,8 +335,7 @@ vendor = vendor.substring(0, vendor.indexOf(" ")); } if (Platform.isWindows()) { - FolderInfo info = (FolderInfo) - Native.loadLibrary("shell32", FolderInfo.class); + FolderInfo info = Native.loadLibrary("shell32", FolderInfo.class); char[] buf = new char[FolderInfo.MAX_PATH]; info.SHGetFolderPathW(null, FolderInfo.CSIDL_APPDATA, null, 0, buf); @@ -358,10 +371,11 @@ return new File(deployment, "deployment.properties"); } - private static final String POLICY_KEY = + private static final String POLICY_KEY = "deployment.user.security.policy"; private static final String CERTS_KEY = "deployment.user.security.trusted.certs"; + @Override public void runBare() throws Throwable { if (runningWebStart()) { super.runBare(); @@ -408,12 +422,11 @@ TestResult result = new TestResult(); test.run(result); if (result.failureCount() != 0) { - Enumeration e = result.failures(); - return ((TestFailure)e.nextElement()).thrownException(); - } - else if (result.errorCount() != 0) { - Enumeration e = result.errors(); - return ((TestFailure)e.nextElement()).thrownException(); + Enumeration e = result.failures(); + return e.nextElement().thrownException(); + } else if (result.errorCount() != 0) { + Enumeration e = result.errors(); + return e.nextElement().thrownException(); } return null; } diff -Nru libjna-java-4.2.2/test/com/sun/jna/win32/W32APIMapperTest.java libjna-java-4.4.0/test/com/sun/jna/win32/W32APIMapperTest.java --- libjna-java-4.2.2/test/com/sun/jna/win32/W32APIMapperTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/win32/W32APIMapperTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2007-2013 Timothy Wall, 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). * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.win32; @@ -26,19 +37,21 @@ final String UNICODE = "[\u0444]"; final String MAGIC = "magic" + UNICODE; - + public static void main(String[] args) { junit.textui.TestRunner.run(W32APIMapperTest.class); } public interface UnicodeLibrary extends Library { public static class TestStructure extends Structure { + public static final List FIELDS = createFieldsOrder("string", "string2", "bool", "bool2"); public String string; public String string2; public boolean bool; public boolean bool2; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "string", "string2", "bool", "bool2" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } String returnWStringArgument(String arg); @@ -47,30 +60,30 @@ } public interface ASCIILibrary extends Library { public static class TestStructure extends Structure { + public static final List FIELDS = Arrays.asList("string", "string2", "bool", "bool2"); public String string; public String string2; public boolean bool; public boolean bool2; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "string", "string2", "bool", "bool2" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } String returnStringArgument(String arg); boolean returnInt32Argument(boolean arg); } - + UnicodeLibrary unicode; ASCIILibrary ascii; - + + @Override protected void setUp() { - unicode = (UnicodeLibrary) - Native.loadLibrary("testlib", UnicodeLibrary.class, - W32APIOptions.UNICODE_OPTIONS); - ascii = (ASCIILibrary) - Native.loadLibrary("testlib", ASCIILibrary.class, - W32APIOptions.ASCII_OPTIONS); + unicode = Native.loadLibrary("testlib", UnicodeLibrary.class, W32APIOptions.UNICODE_OPTIONS); + ascii = Native.loadLibrary("testlib", ASCIILibrary.class, W32APIOptions.ASCII_OPTIONS); } - + + @Override protected void tearDown() { unicode = null; ascii = null; @@ -83,7 +96,7 @@ } Pointer p = Pointer.createConstant(Pointer.SIZE == 8 ? -1 : 0xFFFFFFFFL); assertTrue("Wrong value: " + p, p.toString().endsWith(EXPECTED)); - + } public void testBooleanArgumentConversion() { @@ -91,33 +104,33 @@ unicode.returnInt32Argument(true)); assertFalse("Wrong boolean FALSE argument conversion (unicode)", unicode.returnInt32Argument(false)); - + assertTrue("Wrong boolean TRUE argument conversion (ASCII)", ascii.returnInt32Argument(true)); assertFalse("Wrong boolean FALSE argument conversion (ASCII)", ascii.returnInt32Argument(false)); } - + public void testUnicodeMapping() { assertEquals("Strings should correspond to wide strings", MAGIC, unicode.returnWStringArgument(MAGIC)); String[] args = { "one", "two" }; assertEquals("String arrays should be converted to wchar_t*[] and back", - args[0], + args[0], unicode.returnWideStringArrayElement(args, 0)); } - + public void testASCIIMapping() { assertEquals("Strings should correspond to C strings", MAGIC, ascii.returnStringArgument(MAGIC)); } - + public void testUnicodeStructureSize() { UnicodeLibrary.TestStructure s = new UnicodeLibrary.TestStructure(); assertEquals("Wrong structure size", Pointer.SIZE*2+8, s.size()); } - + public void testASCIIStructureSize() { ASCIILibrary.TestStructure s = new ASCIILibrary.TestStructure(); assertEquals("Wrong structure size", @@ -130,14 +143,14 @@ s.write(); assertEquals("Wrong value written for FALSE", 0, s.getPointer().getInt(Pointer.SIZE*2)); assertEquals("Wrong value written for TRUE", 1, s.getPointer().getInt(Pointer.SIZE*2+4)); - } + } public void testASCIIStructureWriteBoolean() { ASCIILibrary.TestStructure s = new ASCIILibrary.TestStructure(); s.bool2 = true; s.write(); assertEquals("Wrong value written for FALSE", 0, s.getPointer().getInt(Pointer.SIZE*2)); assertEquals("Wrong value written for TRUE", 1, s.getPointer().getInt(Pointer.SIZE*2+4)); - } + } public void testUnicodeStructureReadBoolean() { UnicodeLibrary.TestStructure s = new UnicodeLibrary.TestStructure(); s.getPointer().setInt(Pointer.SIZE*2, 1); @@ -145,7 +158,7 @@ s.read(); assertTrue("Wrong value read for TRUE", s.bool); assertFalse("Wrong value read for FALSE", s.bool2); - } + } public void testASCIIStructureReadBoolean() { ASCIILibrary.TestStructure s = new ASCIILibrary.TestStructure(); s.getPointer().setInt(Pointer.SIZE*2, 1); @@ -153,7 +166,7 @@ s.read(); assertTrue("Wrong value read for TRUE", s.bool); assertFalse("Wrong value read for FALSE", s.bool2); - } + } public void testUnicodeStructureWriteString() { UnicodeLibrary.TestStructure s = new UnicodeLibrary.TestStructure(); s.string = null; diff -Nru libjna-java-4.2.2/test/com/sun/jna/win32/W32StdCallTest.java libjna-java-4.4.0/test/com/sun/jna/win32/W32StdCallTest.java --- libjna-java-4.2.2/test/com/sun/jna/win32/W32StdCallTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/win32/W32StdCallTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,20 +1,30 @@ /* Copyright (c) 2007-2014 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

        - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.win32; import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.HashMap; +import java.util.Collections; import java.util.List; import junit.framework.TestCase; @@ -33,20 +43,24 @@ public static interface TestLibrary extends StdCallLibrary { public static class Inner extends Structure { + public static final List FIELDS = createFieldsOrder("value"); public double value; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "value" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } public static class TestStructure extends Structure { public static class ByValue extends TestStructure implements Structure.ByValue { } + public static final List FIELDS = createFieldsOrder("c", "s", "i", "j", "inner"); public byte c; public short s; public int i; public long j; public Inner inner; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "c", "s", "i", "j", "inner" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } int returnInt32ArgumentStdCall(int arg); @@ -68,20 +82,20 @@ double arg8, NativeLong arg9, NativeLong arg10, NativeLong arg11); } - + public static void main(java.lang.String[] argList) { junit.textui.TestRunner.run(W32StdCallTest.class); } private TestLibrary testlib; - + + @Override protected void setUp() { - testlib = (TestLibrary) - Native.loadLibrary("testlib", TestLibrary.class, new HashMap() { - { put(Library.OPTION_FUNCTION_MAPPER, StdCallLibrary.FUNCTION_MAPPER); } - }); + testlib = Native.loadLibrary("testlib", TestLibrary.class, + Collections.singletonMap(Library.OPTION_FUNCTION_MAPPER, StdCallLibrary.FUNCTION_MAPPER)); } - + + @Override protected void tearDown() { testlib = null; } @@ -91,44 +105,37 @@ NativeLibrary lib = NativeLibrary.getInstance("testlib"); Method[] methods = { - TestLibrary.class.getMethod("returnInt32ArgumentStdCall", - new Class[] { int.class }), - TestLibrary.class.getMethod("returnStructureByValueArgumentStdCall", - new Class[] { - TestLibrary.TestStructure.ByValue.class - }), - TestLibrary.class.getMethod("callInt32StdCallCallback", - new Class[] { - TestLibrary.Int32Callback.class, - int.class, int.class, - }), + TestLibrary.class.getMethod("returnInt32ArgumentStdCall", int.class), + TestLibrary.class.getMethod("returnStructureByValueArgumentStdCall", TestLibrary.TestStructure.ByValue.class), + TestLibrary.class.getMethod("callInt32StdCallCallback", TestLibrary.Int32Callback.class, int.class, int.class) }; - for (int i=0;i < methods.length;i++) { - String name = mapper.getFunctionName(lib, methods[i]); + for (Method m : methods) { + String name = mapper.getFunctionName(lib, m); assertTrue("Function name not decorated for method " - + methods[i].getName() + + m.getName() + ": " + name, name.indexOf("@") != -1); assertEquals("Wrong name in mapped function", name, lib.getFunction(name, StdCallLibrary.STDCALL_CONVENTION).getName()); } } - + public void testStdCallReturnInt32Argument() { final int MAGIC = 0x12345678; assertEquals("Expect zero return", 0, testlib.returnInt32ArgumentStdCall(0)); assertEquals("Expect magic return", MAGIC, testlib.returnInt32ArgumentStdCall(MAGIC)); } - + public void testStdCallReturnStructureByValueArgument() { TestLibrary.TestStructure.ByValue s = new TestLibrary.TestStructure.ByValue(); assertTrue("Wrong struct value", s.dataEquals(testlib.returnStructureByValueArgumentStdCall(s))); } - + public void testStdCallCallback() { final int MAGIC = 0x11111111; final boolean[] called = { false }; TestLibrary.Int32Callback cb = new TestLibrary.Int32Callback() { + @Override public int callback(int arg, int arg2) { called[0] = true; return arg + arg2; @@ -140,9 +147,9 @@ if (value == -1) { fail("stdcall callback did not restore the stack pointer"); } - assertEquals("Wrong stdcall callback value", Integer.toHexString(EXPECTED), + assertEquals("Wrong stdcall callback value", Integer.toHexString(EXPECTED), Integer.toHexString(value)); - + value = testlib.callInt32StdCallCallback(cb, -1, -2); if (value == -1) { fail("stdcall callback did not restore the stack pointer"); @@ -153,6 +160,7 @@ public void testStdCallCallbackStackAlignment() { final boolean[] called = { false }; TestLibrary.ManyArgsStdCallCallback cb = new TestLibrary.ManyArgsStdCallCallback() { + @Override public void callback(NativeLong arg1, int arg2, double arg3, String arg4, String arg5, double arg6, NativeLong arg7, diff -Nru libjna-java-4.2.2/test/com/sun/jna/wince/CoreDLLTest.java libjna-java-4.4.0/test/com/sun/jna/wince/CoreDLLTest.java --- libjna-java-4.2.2/test/com/sun/jna/wince/CoreDLLTest.java 2016-03-16 14:37:28.000000000 +0000 +++ libjna-java-4.4.0/test/com/sun/jna/wince/CoreDLLTest.java 2017-03-14 19:31:03.000000000 +0000 @@ -1,14 +1,25 @@ /* Copyright (c) 2011 Timothy Wall, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *

        - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * 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.wince; @@ -16,7 +27,6 @@ import com.sun.jna.*; import com.sun.jna.ptr.*; import com.sun.jna.win32.*; -import java.util.Arrays; import java.util.List; public class CoreDLLTest extends TestCase { @@ -25,19 +35,27 @@ } public interface CoreDLL extends StdCallLibrary { + CoreDLL INSTANCE = Native.loadLibrary("coredll", CoreDLL.class, W32APIOptions.UNICODE_OPTIONS); + public static class SECURITY_ATTRIBUTES extends Structure { + public static final List FIELDS = createFieldsOrder("dwLength", "lpSecurityDescriptor", "bInheritHandle"); public int dwLength; public Pointer lpSecurityDescriptor; public boolean bInheritHandle; public SECURITY_ATTRIBUTES() { dwLength = size(); } - protected List getFieldOrder() { - return Arrays.asList(new String[] { "dwLength", "lpSecurityDescriptor", "bInheritHandle" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } public static class STARTUPINFO extends Structure { + public static final List FIELDS = createFieldsOrder( + "cb", "lpReserved", "lpDesktop", "lpTitle", "dwX", "dwY", "dwXSize", "dwYSize", + "dwXCountChars", "dwYCountChars", "dwFillAttribute", "dwFlags", "wShowWindow", + "cbReserved2", "lpReserved2", "hStdInput", "hStdOutput", "hStdError"); public int cb; public String lpReserved; public String lpDesktop; @@ -59,11 +77,13 @@ public STARTUPINFO() { cb = size(); } - protected List getFieldOrder() { - return Arrays.asList(new String[] { "cb", "lpReserved", "lpDesktop", "lpTitle", "dwX", "dwY", "dwXSize", "dwYSize", "dwXCountChars", "dwYCountChars", "dwFillAttribute", "dwFlags", "wShowWindow", "cbReserved2", "lpReserved2", "hStdInput", "hStdOutput", "hStdError" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } public static class PROCESS_INFORMATION extends Structure { + public static final List FIELDS = createFieldsOrder("hProcess", "hThread", "dwProcessId", "dwThreadId"); public Pointer hProcess; public Pointer hThread; public int dwProcessId; @@ -72,24 +92,25 @@ public static class ByReference extends PROCESS_INFORMATION implements Structure.ByReference { public ByReference() { } - + public ByReference(Pointer memory) { super(memory); } } - + public PROCESS_INFORMATION() { + super(); } - + public PROCESS_INFORMATION(Pointer memory) { super(memory); } - protected List getFieldOrder() { - return Arrays.asList(new String[] { "hProcess", "hThread", "dwProcessId", "dwThreadId" }); + @Override + protected List getFieldOrder() { + return FIELDS; } } - CoreDLL INSTANCE = (CoreDLL)Native.loadLibrary("coredll", CoreDLL.class, - W32APIOptions.UNICODE_OPTIONS); + boolean CreateProcess(String lpApplicationName, String lpCommandLine, SECURITY_ATTRIBUTES lpProcessAttributes, SECURITY_ATTRIBUTES lpThreadAttributes, @@ -107,7 +128,4 @@ null, null, processInformation); assertTrue("Process launch failed", status); } -} - - - +} \ No newline at end of file