diff --git a/.travis.yml b/.travis.yml index d120ff6e3c..3e1a8dc1c0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ dist: trusty language: java install: - - '[ "${TRAVIS_OS_NAME}" = "linux" ] && wget http://apache.mirror.iphh.net/ant/binaries/apache-ant-1.9.12-bin.tar.gz && tar xzf apache-ant-1.9.12-bin.tar.gz && sudo mv apache-ant-1.9.12 /usr/local/apache-ant-1.9.12 && sudo rm -f /usr/local/ant && sudo ln -s /usr/local/apache-ant-1.9.12 /usr/local/ant && sudo ln -s /usr/local/apache-ant-1.9.12/bin/ant /usr/local/bin/ant || true' + - '[ "${TRAVIS_OS_NAME}" = "linux" ] && wget http://apache.mirror.iphh.net/ant/binaries/apache-ant-1.9.13-bin.tar.gz && tar xzf apache-ant-1.9.13-bin.tar.gz && sudo mv apache-ant-1.9.13 /usr/local/apache-ant-1.9.13 && sudo rm -f /usr/local/ant && sudo ln -s /usr/local/apache-ant-1.9.13 /usr/local/ant && sudo ln -s /usr/local/apache-ant-1.9.13/bin/ant /usr/local/bin/ant || true' - '[ "${TRAVIS_OS_NAME}" = "osx" ] && brew update || true' - '[ "${TRAVIS_OS_NAME}" = "osx" ] && brew uninstall libtool && brew install libtool || true' - '[ "${TRAVIS_OS_NAME}" = "osx" ] && brew install ant || true' diff --git a/CHANGES.md b/CHANGES.md index c9d585b4af..dfedc760d2 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -26,6 +26,7 @@ Features * [#983](https://github.com/java-native-access/jna/issues/983): Added `GetIfEntry`, `GetIfEntry2`, and `GetNetworkParams` and supporting structures `MIB_IFROW`, `MIB_IF_ROW2`, and `FIXED_INFO` to `c.s.j.platform.win32.IPHlpAPI.java` - [@dbwiddis](https://github.com/dbwiddis). * [#984](https://github.com/java-native-access/jna/issues/984): Added `CM_Locate_DevNode`, `CM_Get_Parent`, `CM_Get_Child`, `CM_Get_Sibling`, `CM_Get_Device_ID`, and `CM_Get_Device_ID_Size` to `c.s.j.platform.win32.Cfgmgr32.java` and a `c.s.j.platform.win32.Cfgmgr32Util` class for `CM_Get_Device_ID` - [@dbwiddis](https://github.com/dbwiddis). * [#988](https://github.com/java-native-access/jna/issues/988): Added `PdhLookupPerfIndexByEnglishName` to `c.s.j.platform.win32.PdhUtil` - [@dbwiddis](https://github.com/dbwiddis). +* [#992](https://github.com/java-native-access/jna/pull/992): Improve stability of windows tests and add appveyor configuration for windows CI builds - [@matthiasblaesing](https://github.com/matthiasblaesing). Bug Fixes --------- diff --git a/README.md b/README.md index cf4e61ebf9..2096826a15 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ ![Java Native Access - JNA](https://github.com/java-native-access/jna/raw/master/www/images/jnalogo.jpg "Java Native Access - JNA") [![Build Status](https://travis-ci.org/java-native-access/jna.svg?branch=master)](https://travis-ci.org/java-native-access/jna) +[![Build status](https://ci.appveyor.com/api/projects/status/j6vmpjrw5iktb8iu/branch/master?svg=true)](https://ci.appveyor.com/project/dblock/jna-gsxuq/branch/master) Java Native Access (JNA) ======================== diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000000..07d6b7259f --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,20 @@ +version: 1.0.{build} +image: Visual Studio 2015 + +install: +- cmd: set PATH=%PATH%;c:\cygwin64;c:\cygwin64\bin +- cmd: choco install -y -f -i ant +- cmd: choco install -y -f -i cygwin +- cmd: C:\cygwin64\cygwinsetup.exe --root C:\cygwin64 --local-package-dir C:\cygwin64\packages --quiet-mode --no-desktop --no-startmenu --packages git,make,automake,automake1.15,libtool,mingw64-x86_64-gcc-g++,mingw64-x86_64-gcc-core,gcc-g++ +- cmd: set JAVA_HOME=C:\Program Files\Java\jdk1.8.0 +- cmd: set PATH=%JAVA_HOME%\bin;%PATH% +- cmd: set PATH=c:\cygwin64;c:\cygwin64\bin;%PATH% +- cmd: '"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x64' + +build_script: +- cmd: ant dist + +test_script: +- cmd: net start spooler +- cmd: ant test +- cmd: ant test-platform diff --git a/build.xml b/build.xml index bc20259c54..1c0969a41b 100644 --- a/build.xml +++ b/build.xml @@ -12,7 +12,7 @@ (cross-compile currently only configured/tested on w32ce-arm and android targets) - Use ANT_OPTS=-Dskip-native=false to build native parts, or directly + Use ANT_OPTS=-D-native=true to build native parts, or directly invoke the native or test targets Use ANT_OPTS=-Dheadless to run tests headless Use ANT_OPTS=-Drelease to stage a final, non-snapshot version diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Pdh.java b/contrib/platform/src/com/sun/jna/platform/win32/Pdh.java index f63fae7721..82d13a8e92 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Pdh.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Pdh.java @@ -23,8 +23,6 @@ */ 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; @@ -55,6 +53,12 @@ public interface Pdh extends StdCallLibrary { /** Maximum full counter log name length. */ int PDH_MAX_DATASOURCE_PATH = 1024; + int PDH_MORE_DATA = 0x800007D2; + int PDH_INVALID_ARGUMENT = 0xC0000BBD; + int PDH_MEMORY_ALLOCATION_FAILURE = 0xC0000BBB; + int PDH_CSTATUS_NO_MACHINE = 0x800007D0; + int PDH_CSTATUS_NO_OBJECT = 0xC0000BB8; + /* TODO * LPVOID CALLBACK AllocateMemory(_In_ SIZE_T AllocSize,_In_ LPVOID pContext) * void CALLBACK FreeMemory(LPVOID pBuffer,LPVOID pContext) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/PdhUtil.java b/contrib/platform/src/com/sun/jna/platform/win32/PdhUtil.java index 4143e41374..b246874106 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/PdhUtil.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/PdhUtil.java @@ -30,6 +30,7 @@ import com.sun.jna.Native; import com.sun.jna.platform.win32.WinDef.DWORD; import com.sun.jna.platform.win32.WinDef.DWORDByReference; +import java.util.Collections; /** * Pdh utility API. @@ -61,16 +62,23 @@ public abstract class PdhUtil { public static String PdhLookupPerfNameByIndex(String szMachineName, int dwNameIndex) { // Call once to get required buffer size DWORDByReference pcchNameBufferSize = new DWORDByReference(new DWORD(0)); - Pdh.INSTANCE.PdhLookupPerfNameByIndex(szMachineName, dwNameIndex, null, pcchNameBufferSize); - + int result = Pdh.INSTANCE.PdhLookupPerfNameByIndex(szMachineName, dwNameIndex, null, pcchNameBufferSize); + if(result != WinError.ERROR_SUCCESS && result != Pdh.PDH_MORE_DATA) { + throw new PdhException(result); + } + // Can't allocate 0 memory if (pcchNameBufferSize.getValue().intValue() < 1) { return ""; } // Allocate buffer and call again Memory mem = new Memory(pcchNameBufferSize.getValue().intValue() * CHAR_TO_BYTES); - Pdh.INSTANCE.PdhLookupPerfNameByIndex(szMachineName, dwNameIndex, mem, pcchNameBufferSize); + result = Pdh.INSTANCE.PdhLookupPerfNameByIndex(szMachineName, dwNameIndex, mem, pcchNameBufferSize); + if(result != WinError.ERROR_SUCCESS) { + throw new PdhException(result); + } + // Convert buffer to Java String if (CHAR_TO_BYTES == 1) { return mem.getString(0); @@ -113,9 +121,8 @@ public static int PdhLookupPerfIndexByEnglishName(String szNameBuffer) { /** * Utility method to call Pdh's PdhEnumObjectItems that allocates the - * required memory for the mszCounterList parameter based on the type - * mapping used, calls to PdhEnumObjectItems, and returns the received lists - * of strings. + * required memory for the lists parameters based on the type mapping used, + * calls to PdhEnumObjectItems, and returns the received lists of strings. * * @param szDataSource * String that specifies the name of the log file used to @@ -137,113 +144,135 @@ public static int PdhLookupPerfIndexByEnglishName(String szNameBuffer) { * returned. * @return Returns a List of Strings of the counters for the object. */ - public static List PdhEnumObjectItemCounters(String szDataSource, String szMachineName, String szObjectName, + public static PdhEnumObjectItems PdhEnumObjectItems(String szDataSource, String szMachineName, String szObjectName, int dwDetailLevel) { List counters = new ArrayList(); + List instances = new ArrayList(); // Call once to get string lengths DWORDByReference pcchCounterListLength = new DWORDByReference(new DWORD(0)); DWORDByReference pcchInstanceListLength = new DWORDByReference(new DWORD(0)); - Pdh.INSTANCE.PdhEnumObjectItems(szDataSource, szMachineName, szObjectName, null, pcchCounterListLength, null, + int result = Pdh.INSTANCE.PdhEnumObjectItems(szDataSource, szMachineName, szObjectName, null, pcchCounterListLength, null, pcchInstanceListLength, dwDetailLevel, 0); + if(result != WinError.ERROR_SUCCESS && result != Pdh.PDH_MORE_DATA) { + throw new PdhException(result); + } - // Can't allocate 0 memory if no counters - if (pcchCounterListLength.getValue().intValue() < 1) { - return counters; + Memory mszCounterList = null; + Memory mszInstanceList = null; + + if (pcchCounterListLength.getValue().intValue() > 0) { + mszCounterList = new Memory(pcchCounterListLength.getValue().intValue() * CHAR_TO_BYTES); + } + + if (pcchInstanceListLength.getValue().intValue() > 0) { + mszInstanceList = new Memory(pcchInstanceListLength.getValue().intValue() * CHAR_TO_BYTES); + } + + result = Pdh.INSTANCE.PdhEnumObjectItems(szDataSource, szMachineName, szObjectName, mszCounterList, + pcchCounterListLength, mszInstanceList, pcchInstanceListLength, dwDetailLevel, 0); + + if(result != WinError.ERROR_SUCCESS) { + throw new PdhException(result); } - // Allocate memory and call again to populate strings - Memory mszCounterList = new Memory(pcchCounterListLength.getValue().intValue() * CHAR_TO_BYTES); - // Don't need the instances - pcchInstanceListLength.getValue().setValue(0); - Pdh.INSTANCE.PdhEnumObjectItems(szDataSource, szMachineName, szObjectName, mszCounterList, - pcchCounterListLength, null, pcchInstanceListLength, dwDetailLevel, 0); // Fetch counters - int offset = 0; - while (offset < mszCounterList.size()) { - String s = null; - if (CHAR_TO_BYTES == 1) { - s = mszCounterList.getString(offset); - } else { - s = mszCounterList.getWideString(offset); + if (mszCounterList != null) { + int offset = 0; + while (offset < mszCounterList.size()) { + String s = null; + if (CHAR_TO_BYTES == 1) { + s = mszCounterList.getString(offset); + } else { + s = mszCounterList.getWideString(offset); + } + // list ends with double null + if (s.isEmpty()) { + break; + } + counters.add(s); + // Increment for string + null terminator + offset += (s.length() + 1) * CHAR_TO_BYTES; } - // list ends with double null - if (s.isEmpty()) { - break; + } + + if(mszInstanceList != null) { + int offset = 0; + while (offset < mszInstanceList.size()) { + String s = null; + if (CHAR_TO_BYTES == 1) { + s = mszInstanceList.getString(offset); + } else { + s = mszInstanceList.getWideString(offset); + } + // list ends with double null + if (s.isEmpty()) { + break; + } + instances.add(s); + // Increment for string + null terminator + offset += (s.length() + 1) * CHAR_TO_BYTES; } - counters.add(s); - // Increment for string + null terminator - offset += (s.length() + 1) * CHAR_TO_BYTES; } - return counters; + return new PdhEnumObjectItems(counters, instances); } + /** - * Utility method to call Pdh's PdhEnumObjectItems that allocates the - * required memory for the mszInstanceList parameters based on the type - * mapping used, calls to PdhEnumObjectItems, and returns the received lists - * of strings. - * - * @param szDataSource - * String that specifies the name of the log file used to - * enumerate the counter and instance names. If NULL, the - * function uses the computer specified in the szMachineName - * parameter to enumerate the names. - * @param szMachineName - * String that specifies the name of the computer that contains - * the counter and instance names that you want to enumerate. - * Include the leading slashes in the computer name, for example, - * \\computername. If the szDataSource parameter is NULL, you can - * set szMachineName to NULL to specify the local computer. - * @param szObjectName - * String that specifies the name of the object whose counter and - * instance names you want to enumerate. - * @param dwDetailLevel - * Detail level of the performance items to return. All items - * that are of the specified detail level or less will be - * returned. - * @return Returns a Lists of Strings of the instances of the object. + * Holder Object for PdhEnumObjectsItems. The embedded lists are modifiable + * lists and can be accessed through the {@link #getCounters()} and + * {@link #getInstances()} accessors. */ - public static List PdhEnumObjectItemInstances(String szDataSource, String szMachineName, - String szObjectName, int dwDetailLevel) { - List instances = new ArrayList(); + public static class PdhEnumObjectItems { + private final List counters; + private final List instances; - // Call once to get string lengths - DWORDByReference pcchCounterListLength = new DWORDByReference(new DWORD(0)); - DWORDByReference pcchInstanceListLength = new DWORDByReference(new DWORD(0)); - Pdh.INSTANCE.PdhEnumObjectItems(szDataSource, szMachineName, szObjectName, null, pcchCounterListLength, null, - pcchInstanceListLength, dwDetailLevel, 0); + public PdhEnumObjectItems(List counters, List instances) { + this.counters = copyAndEmptyListForNullList(counters); + this.instances = copyAndEmptyListForNullList(instances); + } + + /** + * @return the embedded counters list, all calls to this function receive + * the same list and thus share modifications + */ + public List getCounters() { + return counters; + } - // Can't allocate 0 memory if no instances - if (pcchInstanceListLength.getValue().intValue() < 1) { + /** + * @return the embedded instances list, all calls to this function receive + * the same list and thus share modifications + */ + public List getInstances() { return instances; } - // Allocate memory and call again to populate strings - Memory mszInstanceList = new Memory(pcchInstanceListLength.getValue().intValue() * CHAR_TO_BYTES); - // Don't need the counters - pcchCounterListLength.getValue().setValue(0); - Pdh.INSTANCE.PdhEnumObjectItems(szDataSource, szMachineName, szObjectName, null, pcchCounterListLength, - mszInstanceList, pcchInstanceListLength, dwDetailLevel, 0); - - // Fetch instances - int offset = 0; - while (offset < mszInstanceList.size()) { - String s = null; - if (CHAR_TO_BYTES == 1) { - s = mszInstanceList.getString(offset); + + private List copyAndEmptyListForNullList (List inputList) { + if(inputList == null) { + return new ArrayList(); } else { - s = mszInstanceList.getWideString(offset); - } - // list ends with double null - if (s.isEmpty()) { - break; + return new ArrayList(inputList); } - instances.add(s); - // Increment for string + null terminator - offset += (s.length() + 1) * CHAR_TO_BYTES; } - return instances; + @Override + public String toString() { + return "PdhEnumObjectItems{" + "counters=" + counters + ", instances=" + instances + '}'; + } + } + + public static final class PdhException extends RuntimeException { + private final int errorCode; + + public PdhException(int errorCode) { + super(String.format("Pdh call failed with error code 0x%08X", errorCode)); + this.errorCode = errorCode; + } + + public int getErrorCode() { + return errorCode; + } } } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WTypes.java b/contrib/platform/src/com/sun/jna/platform/win32/WTypes.java index b5e3b76a7d..03dc44230a 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WTypes.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WTypes.java @@ -212,7 +212,7 @@ public String toString() { } public static class LPWSTR extends PointerType { - public static class ByReference extends BSTR implements + public static class ByReference extends LPWSTR implements Structure.ByReference { } diff --git a/contrib/platform/test/com/sun/jna/platform/win32/AbstractWin32TestSupport.java b/contrib/platform/test/com/sun/jna/platform/win32/AbstractWin32TestSupport.java index f59b5a9372..87535cf342 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/AbstractWin32TestSupport.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/AbstractWin32TestSupport.java @@ -145,4 +145,38 @@ public static void killProcessByName(String filename) { } Kernel32.INSTANCE.CloseHandle(hSnapShot); } + + /** + * Return true if the supplied uuid can be found in the registry. + * + * @param uuid Format: {<UID>} + */ + public static boolean checkCOMRegistered(String uuid) { + WinReg.HKEYByReference phkKey = null; + try { + phkKey = Advapi32Util.registryGetKey(WinReg.HKEY_CLASSES_ROOT, "Interface\\" + uuid, WinNT.KEY_READ); + if(phkKey != null) { + return true; + } + } catch (Win32Exception ex) { + // Ok - failed ... + } finally { + if(phkKey != null && phkKey.getValue() != null) { + Advapi32Util.registryCloseKey(phkKey.getValue()); + } + } + try { + phkKey = Advapi32Util.registryGetKey(WinReg.HKEY_CLASSES_ROOT, "CLSID\\" + uuid, WinNT.KEY_READ); + if(phkKey != null) { + return true; + } + } catch (Win32Exception ex) { + // Ok - failed ... + } finally { + if(phkKey != null && phkKey.getValue() != null) { + Advapi32Util.registryCloseKey(phkKey.getValue()); + } + } + return false; + } } diff --git a/contrib/platform/test/com/sun/jna/platform/win32/COM/EnumMoniker_Test.java b/contrib/platform/test/com/sun/jna/platform/win32/COM/EnumMoniker_Test.java index c2e4d1aa45..0cff45c16e 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/COM/EnumMoniker_Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/COM/EnumMoniker_Test.java @@ -13,6 +13,7 @@ package com.sun.jna.platform.win32.COM; import com.sun.jna.Pointer; +import static com.sun.jna.platform.win32.AbstractWin32TestSupport.checkCOMRegistered; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; @@ -32,6 +33,7 @@ import com.sun.jna.platform.win32.COM.util.annotation.ComObject; import com.sun.jna.platform.win32.COM.util.annotation.ComProperty; import com.sun.jna.ptr.PointerByReference; +import org.junit.Assume; public class EnumMoniker_Test { static { @@ -54,15 +56,17 @@ interface Application { interface MsWordApp extends Application { } - ObjectFactory factory; - MsWordApp ob1; - MsWordApp ob2; + private ObjectFactory factory; + private MsWordApp ob1; + private MsWordApp ob2; + private boolean initialized = false; @Before public void before() { - WinNT.HRESULT hr = Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED); - COMUtils.checkRC(hr); - + // Check Existence of Word Application + Assume.assumeTrue("Could not find registration", checkCOMRegistered("{00020970-0000-0000-C000-000000000046}")); + COMUtils.checkRC(Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED)); + initialized = true; this.factory = new ObjectFactory(); // Two COM objects are require to be running for these tests to work this.ob1 = this.factory.createObject(MsWordApp.class); @@ -77,7 +81,12 @@ public void after() { if(ob2 != null) { ob2.Quit(); } - Ole32.INSTANCE.CoUninitialize(); + if(factory != null) { + factory.disposeAll(); + } + if(initialized) { + Ole32.INSTANCE.CoUninitialize(); + } } @Test diff --git a/contrib/platform/test/com/sun/jna/platform/win32/COM/ITypeLibTest.java b/contrib/platform/test/com/sun/jna/platform/win32/COM/ITypeLibTest.java index c2eb871d74..1f4e78c7a7 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/COM/ITypeLibTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/COM/ITypeLibTest.java @@ -14,9 +14,7 @@ import com.sun.jna.Native; import com.sun.jna.Pointer; -import junit.framework.TestCase; -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; @@ -33,24 +31,25 @@ import com.sun.jna.platform.win32.WinDef.USHORTByReference; import com.sun.jna.platform.win32.WinNT.HRESULT; import com.sun.jna.ptr.PointerByReference; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import org.junit.Test; /** * @author dblock[at]dblock[dot]org */ -public class ITypeLibTest extends TestCase { +public class ITypeLibTest { 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); - } public ITypeLibTest() { } @@ -73,12 +72,17 @@ private ITypeLib loadShellTypeLib() { return new TypeLib(pShellTypeLib.getValue()); } + @Test public void testGetTypeInfoCount() { ITypeLib shellTypeLib = loadShellTypeLib(); UINT typeInfoCount = shellTypeLib.GetTypeInfoCount(); - assertEquals(38, typeInfoCount.intValue()); + // Validate correct method count range + // Observed values in the wild were 37 (Windows 2012 Serve R2) + 38 + assertTrue(typeInfoCount.intValue() >= 30); + assertTrue(typeInfoCount.intValue() <= 40); } + @Test public void testGetTypeInfo() { ITypeLib shellTypeLib = loadShellTypeLib(); @@ -90,6 +94,7 @@ public void testGetTypeInfo() { //System.out.println("ITypeInfo: " + ppTInfo.toString()); } + @Test public void testGetTypeInfoType() { ITypeLib shellTypeLib = loadShellTypeLib(); @@ -101,6 +106,7 @@ public void testGetTypeInfoType() { //System.out.println("TYPEKIND: " + pTKind); } + @Test public void testGetTypeInfoOfGuid() { ITypeLib shellTypeLib = loadShellTypeLib(); @@ -112,6 +118,7 @@ public void testGetTypeInfoOfGuid() { assertTrue(COMUtils.SUCCEEDED(hr)); } + @Test public void testLibAttr() { ITypeLib shellTypeLib = loadShellTypeLib(); @@ -129,6 +136,7 @@ public void testLibAttr() { shellTypeLib.ReleaseTLibAttr(tlibAttr); } + @Test public void testGetTypeComp() { ITypeLib shellTypeLib = loadShellTypeLib(); @@ -139,6 +147,7 @@ public void testGetTypeComp() { assertTrue(COMUtils.SUCCEEDED(hr)); } + @Test public void testIsName() { ITypeLib shellTypeLib = loadShellTypeLib(); @@ -157,7 +166,8 @@ public void testIsName() { Ole32.INSTANCE.CoTaskMemFree(p); } - + + @Test public void testFindName() { ITypeLib shellTypeLib = loadShellTypeLib(); diff --git a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacks2_Test.java b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacks2_Test.java index d47406e31a..0603465b82 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacks2_Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacks2_Test.java @@ -1,6 +1,8 @@ package com.sun.jna.platform.win32.COM.util; import com.sun.jna.Pointer; +import static com.sun.jna.platform.win32.AbstractWin32TestSupport.checkCOMRegistered; +import com.sun.jna.platform.win32.COM.COMUtils; 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; @@ -8,6 +10,7 @@ import com.sun.jna.platform.win32.Variant; import org.junit.After; import org.junit.Assert; +import org.junit.Assume; import org.junit.Before; import org.junit.Test; @@ -17,18 +20,26 @@ public class ComEventCallbacks2_Test { ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true); } - Factory factory; + private boolean initialized = false; + private Factory factory; @Before public void before() { - Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED); + // Check if Word is registered in the registry + Assume.assumeTrue("Could not find registration", checkCOMRegistered("{000209FF-0000-0000-C000-000000000046}")); + COMUtils.checkRC(Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED)); + initialized = true; this.factory = new Factory(); } @After public void after() { - this.factory.disposeAll(); - Ole32.INSTANCE.CoUninitialize(); + if(this.factory != null) { + this.factory.disposeAll(); + } + if(initialized) { + Ole32.INSTANCE.CoUninitialize(); + } } @Test diff --git a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacksFactory_Test.java b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacksFactory_Test.java index 81690365c5..7f88981def 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacksFactory_Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacksFactory_Test.java @@ -13,6 +13,7 @@ package com.sun.jna.platform.win32.COM.util; import com.sun.jna.platform.win32.AbstractWin32TestSupport; +import static com.sun.jna.platform.win32.AbstractWin32TestSupport.checkCOMRegistered; import com.sun.jna.platform.win32.COM.COMUtils; import org.junit.After; import org.junit.Assert; @@ -36,6 +37,7 @@ 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.*; +import org.junit.Assume; public class ComEventCallbacksFactory_Test { @@ -47,6 +49,8 @@ public class ComEventCallbacksFactory_Test { @Before public void before() { + // Check that Internet Explorer is registered in the registry + Assume.assumeTrue("Could not find registration", checkCOMRegistered("{0002DF01-0000-0000-C000-000000000046}")); AbstractWin32TestSupport.killProcessByName("iexplore.exe"); try { Thread.sleep(5 * 1000); @@ -63,8 +67,10 @@ public void uncaughtException(Thread t, Throwable e) { @After public void after() { - this.factory.disposeAll(); - this.factory.getComThread().terminate(10000); + if(this.factory != null) { + this.factory.disposeAll(); + this.factory.getComThread().terminate(10000); + } } diff --git a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacksObjectFactory_Test.java b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacksObjectFactory_Test.java index 405e0ea9bd..5babe876cc 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacksObjectFactory_Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacksObjectFactory_Test.java @@ -14,6 +14,7 @@ import com.sun.jna.Pointer; import com.sun.jna.platform.win32.AbstractWin32TestSupport; +import static com.sun.jna.platform.win32.AbstractWin32TestSupport.checkCOMRegistered; import com.sun.jna.platform.win32.COM.COMUtils; import org.junit.After; import org.junit.Assert; @@ -38,6 +39,7 @@ 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.*; +import org.junit.Assume; public class ComEventCallbacksObjectFactory_Test { @@ -45,22 +47,30 @@ public class ComEventCallbacksObjectFactory_Test { ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true); } - ObjectFactory factory; + private boolean initialized = false; + private ObjectFactory factory; @Before public void before() { + // Check that Internet Explorer is registered in the registry + Assume.assumeTrue("Could not find registration", checkCOMRegistered("{0002DF01-0000-0000-C000-000000000046}")); AbstractWin32TestSupport.killProcessByName("iexplore.exe"); try { Thread.sleep(5 * 1000); } catch (InterruptedException ex) {} - Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED); + COMUtils.checkRC(Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED)); + initialized= true; this.factory = new ObjectFactory(); } @After public void after() { - this.factory.disposeAll(); - Ole32.INSTANCE.CoUninitialize(); + if(this.factory != null) { + this.factory.disposeAll(); + } + if(initialized) { + Ole32.INSTANCE.CoUninitialize(); + } } diff --git a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ConfigurateLCID_Test.java b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ConfigurateLCID_Test.java index 098247f709..e237be1a2e 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ConfigurateLCID_Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ConfigurateLCID_Test.java @@ -1,12 +1,15 @@ package com.sun.jna.platform.win32.COM.util; import com.sun.jna.Pointer; +import static com.sun.jna.platform.win32.AbstractWin32TestSupport.checkCOMRegistered; +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.Ole32; import com.sun.jna.platform.win32.WinDef.LCID; import org.junit.After; import org.junit.Assert; +import org.junit.Assume; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; @@ -14,11 +17,15 @@ public class ConfigurateLCID_Test { + private boolean initialized = false; private Factory factory; @Before public void before() { - Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED); + // Check that Excel is registered in the registry + Assume.assumeTrue("Could not find registration", checkCOMRegistered("{0002DF01-0000-0000-C000-000000000046}")); + COMUtils.checkRC(Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED)); + initialized= true; this.factory = new Factory(); // switch to english locale (the test is only valid if office is // installed in a non-english locale @@ -27,8 +34,12 @@ public void before() { @After public void after() { - this.factory.disposeAll(); - Ole32.INSTANCE.CoUninitialize(); + if(this.factory != null) { + this.factory.disposeAll(); + } + if(initialized) { + Ole32.INSTANCE.CoUninitialize(); + } } @Test diff --git a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ConvertTest.java b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ConvertTest.java index bc1971bff6..8f2ed02a55 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ConvertTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ConvertTest.java @@ -1,10 +1,11 @@ package com.sun.jna.platform.win32.COM.util; import com.sun.jna.Pointer; +import static com.sun.jna.platform.win32.AbstractWin32TestSupport.checkCOMRegistered; +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.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; @@ -20,25 +21,34 @@ import org.junit.AfterClass; import org.junit.Test; import static org.junit.Assert.*; +import org.junit.Assume; import org.junit.BeforeClass; // Untested: IDispatch // Untested: Proxy public class ConvertTest { + private static boolean initialized = false; private static ObjectFactory fact; @BeforeClass public static void init() { - Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED); + // Check that FileSystemObject is registered in the registry + Assume.assumeTrue("Could not find registration", checkCOMRegistered("{0D43FE01-F093-11CF-8940-00A0C9054228}")); + COMUtils.checkRC(Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED)); + initialized = true; fact = new ObjectFactory(); } @AfterClass public static void destruct() { - fact.disposeAll(); + if(fact != null) { + fact.disposeAll(); + } fact = null; - Ole32.INSTANCE.CoUninitialize(); + if(initialized) { + Ole32.INSTANCE.CoUninitialize(); + } } @Test diff --git a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/HybdridCOMInvocationTest.java b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/HybdridCOMInvocationTest.java index f55a0b69c8..353d80a4b8 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/HybdridCOMInvocationTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/HybdridCOMInvocationTest.java @@ -1,6 +1,7 @@ package com.sun.jna.platform.win32.COM.util; import com.sun.jna.Pointer; +import static com.sun.jna.platform.win32.AbstractWin32TestSupport.checkCOMRegistered; import com.sun.jna.platform.win32.COM.COMException; import com.sun.jna.platform.win32.COM.COMLateBindingObject; import com.sun.jna.platform.win32.COM.COMUtils; @@ -33,6 +34,7 @@ import org.junit.After; import org.junit.Test; import static org.junit.Assert.*; +import org.junit.Assume; import org.junit.Before; /** @@ -59,15 +61,23 @@ public class HybdridCOMInvocationTest { private static final GUID CLSID_WORD = new GUID(CLSID_WORD_STRING); private static final IID IID_APPLICATION = new IID(new GUID(IID_APPLICATION_STRING)); + private boolean initialized = false; + @After public void tearDown() throws Exception { - Ole32.INSTANCE.CoUninitialize(); + if(initialized) { + Ole32.INSTANCE.CoUninitialize(); + initialized = false; + } } @Before public void setUp() throws Exception { // Initialize COM for this thread... - Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED); + // Check that FileSystemObject is registered in the registry + Assume.assumeTrue("Could not find registration", checkCOMRegistered(CLSID_WORD_STRING)); + COMUtils.checkRC(Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED)); + initialized = true; } @Test diff --git a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/IDispatchTest.java b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/IDispatchTest.java index 11c123f526..3c188d2968 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/IDispatchTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/IDispatchTest.java @@ -2,6 +2,8 @@ import com.sun.jna.Pointer; import com.sun.jna.platform.win32.AbstractWin32TestSupport; +import static com.sun.jna.platform.win32.AbstractWin32TestSupport.checkCOMRegistered; +import com.sun.jna.platform.win32.COM.COMUtils; 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; @@ -14,25 +16,34 @@ import org.junit.Test; import static org.junit.Assert.*; +import org.junit.Assume; public class IDispatchTest { - - ObjectFactory factory; + private boolean initialized = false; + private ObjectFactory factory; @Before public void before() { + Assume.assumeTrue("Could not find registration", checkCOMRegistered("{0002DF01-0000-0000-C000-000000000046}")); + AbstractWin32TestSupport.killProcessByName("iexplore.exe"); try { Thread.sleep(5 * 1000); } catch (InterruptedException ex) {} - Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED); + COMUtils.checkRC(Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED)); + initialized = true; this.factory = new ObjectFactory(); } @After public void after() { - this.factory.disposeAll(); - Ole32.INSTANCE.CoUninitialize(); + if(this.factory != null) { + this.factory.disposeAll(); + } + if(initialized) { + Ole32.INSTANCE.CoUninitialize(); + initialized = false; + } } @Test diff --git a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ProxyObjectFactory_Test.java b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ProxyObjectFactory_Test.java index d543bc7f81..639a8b5df5 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ProxyObjectFactory_Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ProxyObjectFactory_Test.java @@ -12,6 +12,7 @@ */ package com.sun.jna.platform.win32.COM.util; +import static com.sun.jna.platform.win32.AbstractWin32TestSupport.checkCOMRegistered; import com.sun.jna.platform.win32.COM.COMException; import com.sun.jna.platform.win32.COM.COMInvokeException; import static org.junit.Assert.*; @@ -29,6 +30,7 @@ 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.WinError; +import org.junit.Assume; public class ProxyObjectFactory_Test { private static final Logger LOG = Logger.getLogger(ProxyObjectFactory_Test.class.getName()); @@ -98,10 +100,13 @@ public long getValue() { interface MsWordApp extends Application { } - Factory factory; + private Factory factory; @Before public void before() { + // Check Existence of Word Application + Assume.assumeTrue("Could not find registration", checkCOMRegistered("{00020970-0000-0000-C000-000000000046}")); + this.factory = new Factory(); //ensure there are no word applications running. while(true) { @@ -139,8 +144,11 @@ public void before() { @After public void after() { + if(factory != null) { factory.disposeAll(); factory.getComThread().terminate(10000); + factory = null; + } } @Test diff --git a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ProxyObjectObjectFactory_Test.java b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ProxyObjectObjectFactory_Test.java index f1753a0b55..56ff0ff0b2 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ProxyObjectObjectFactory_Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ProxyObjectObjectFactory_Test.java @@ -13,8 +13,10 @@ package com.sun.jna.platform.win32.COM.util; import com.sun.jna.Pointer; +import static com.sun.jna.platform.win32.AbstractWin32TestSupport.checkCOMRegistered; import com.sun.jna.platform.win32.COM.COMException; import com.sun.jna.platform.win32.COM.COMInvokeException; +import com.sun.jna.platform.win32.COM.COMUtils; import static org.junit.Assert.*; import java.lang.reflect.Proxy; @@ -32,6 +34,7 @@ import com.sun.jna.platform.win32.COM.util.annotation.ComProperty; import com.sun.jna.platform.win32.Ole32; import com.sun.jna.platform.win32.WinError; +import org.junit.Assume; public class ProxyObjectObjectFactory_Test { private static final Logger LOG = Logger.getLogger(ProxyObjectObjectFactory_Test.class.getName()); @@ -101,11 +104,15 @@ public long getValue() { interface MsWordApp extends Application { } - ObjectFactory factory; + private ObjectFactory factory; + private boolean initialized = false; @Before public void before() { - Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED); + // Check Existence of Word Application + Assume.assumeTrue("Could not find registration", checkCOMRegistered("{00020970-0000-0000-C000-000000000046}")); + COMUtils.checkRC(Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED)); + initialized = true; this.factory = new ObjectFactory(); //ensure there are no word applications running. while(true) { @@ -143,8 +150,12 @@ public void before() { @After public void after() { + if(factory != null) { factory.disposeAll(); + } + if(initialized) { Ole32.INSTANCE.CoUninitialize(); + } } @Test diff --git a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/RunningObjectTable_Test.java b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/RunningObjectTable_Test.java index c95784d77a..58e91a263d 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/RunningObjectTable_Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/RunningObjectTable_Test.java @@ -13,6 +13,7 @@ package com.sun.jna.platform.win32.COM.util; import com.sun.jna.Pointer; +import static com.sun.jna.platform.win32.AbstractWin32TestSupport.checkCOMRegistered; import static org.junit.Assert.*; import java.util.List; @@ -22,11 +23,13 @@ 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.Ole32; +import org.junit.Assume; public class RunningObjectTable_Test { @@ -50,12 +53,18 @@ interface Application extends IUnknown { interface MsWordApp extends Application { } - ObjectFactory factory; - MsWordApp msWord; + private ObjectFactory factory; + private MsWordApp msWord; + private boolean initialized = false; @Before public void before() { - Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED); + // Check Existence of Word Application + Assume.assumeTrue("Could not find registration", checkCOMRegistered("{00020970-0000-0000-C000-000000000046}")); + + COMUtils.checkRC(Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED)); + initialized = true; + this.factory = new ObjectFactory(); //ensure there is only one word application running. while(true) { @@ -85,15 +94,21 @@ public void before() { @After public void after() { - this.msWord.Quit(true, null, null); - try { - //wait for it to quit - Thread.sleep(100); - } catch (InterruptedException e) { - e.printStackTrace(); - } + if(this.msWord != null) { + this.msWord.Quit(true, null, null); + } + try { + //wait for it to quit + Thread.sleep(100); + } catch (InterruptedException e) { + e.printStackTrace(); + } + if(factory != null) { factory.disposeAll(); + } + if(initialized) { Ole32.INSTANCE.CoUninitialize(); + } } @Test diff --git a/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java b/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java index e0bfe5c0dd..9f3ba65f25 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java @@ -335,8 +335,6 @@ public void testGetCurrentThread() { 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() { @@ -355,8 +353,6 @@ public void testGetCurrentProcess() { 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() { diff --git a/contrib/platform/test/com/sun/jna/platform/win32/PdhTest.java b/contrib/platform/test/com/sun/jna/platform/win32/PdhTest.java index a3462c7b47..e78f632211 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/PdhTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/PdhTest.java @@ -16,7 +16,6 @@ import java.util.Collection; import java.util.HashMap; import java.util.LinkedList; -import java.util.List; import java.util.Map; import org.junit.Test; @@ -24,6 +23,8 @@ import com.sun.jna.Native; import com.sun.jna.platform.win32.Pdh.PDH_COUNTER_PATH_ELEMENTS; import com.sun.jna.platform.win32.Pdh.PDH_RAW_COUNTER; +import com.sun.jna.platform.win32.PdhUtil.PdhEnumObjectItems; +import com.sun.jna.platform.win32.PdhUtil.PdhException; import com.sun.jna.platform.win32.WinDef.DWORD; import com.sun.jna.platform.win32.WinDef.DWORDByReference; import com.sun.jna.platform.win32.WinNT.HANDLE; @@ -182,21 +183,32 @@ public void testLookupPerfIndex() { @Test public void testEnumObjectItems() { if (AbstractWin32TestSupport.isEnglishLocale) { - String processorStr = "Processor"; + String processorStr = "Processor"; String processorTimeStr = "% Processor Time"; // Fetch the counter and instance names - List instances = PdhUtil.PdhEnumObjectItemInstances(null, null, processorStr, 100); + PdhEnumObjectItems objects = PdhUtil.PdhEnumObjectItems(null, null, processorStr, 100); - // Should have at least one processor and total instance - assertTrue(instances.contains("0")); - assertTrue(instances.contains("_Total")); + assertTrue(objects.getInstances().contains("0")); + assertTrue(objects.getInstances().contains("_Total")); // Should have a "% Processor Time" counter - List counters = PdhUtil.PdhEnumObjectItemCounters(null, null, processorStr, 100); - assertTrue(counters.contains(processorTimeStr)); + assertTrue(objects.getCounters().contains(processorTimeStr)); } else { System.err.println("testEnumObjectItems test can only be run with english locale."); } } + + @Test + public void testEnumObjectItemsNonExisting() { + Exception caughtException = null; + try { + PdhUtil.PdhEnumObjectItems(null, null, "Unknown counter", 100); + } catch (Exception ex) { + caughtException = ex; + } + assertNotNull(caughtException); + assertTrue(caughtException instanceof PdhException); + assertEquals(Pdh.PDH_CSTATUS_NO_OBJECT, ((PdhException) caughtException).getErrorCode()); + } } diff --git a/contrib/platform/test/com/sun/jna/platform/win32/SAFEARRAYTest.java b/contrib/platform/test/com/sun/jna/platform/win32/SAFEARRAYTest.java index 164f783e71..4e63a883b1 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/SAFEARRAYTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/SAFEARRAYTest.java @@ -14,6 +14,7 @@ import com.sun.jna.Pointer; import com.sun.jna.Structure; +import static com.sun.jna.platform.win32.AbstractWin32TestSupport.checkCOMRegistered; import com.sun.jna.platform.win32.COM.COMException; import com.sun.jna.platform.win32.COM.COMUtils; import com.sun.jna.platform.win32.COM.util.ObjectFactory; @@ -63,6 +64,7 @@ import com.sun.jna.platform.win32.WTypes.VARTYPE; import com.sun.jna.platform.win32.WinDef.LONG; import java.lang.reflect.Field; +import org.junit.Assume; public class SAFEARRAYTest { static { @@ -492,7 +494,11 @@ public void testADODB() { // 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); + try { + conn.Open("Provider=Search.CollatorDSO;Extended Properties='Application=Windows';", "", "", -1); + } catch (COMException ex) { + Assume.assumeNoException(ex); + } 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); diff --git a/contrib/platform/test/com/sun/jna/platform/win32/User32Test.java b/contrib/platform/test/com/sun/jna/platform/win32/User32Test.java index ebd371e421..74f6b7828f 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/User32Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/User32Test.java @@ -379,13 +379,18 @@ public void testSetCursorPos() { 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); + 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); + assertTrue(String.format( + "X coordinate in POINT should be original cursor position - 20 (Old: %dx%d, New: %dx%d)", + cursorPos.x, cursorPos.y, cursorPos2.x, cursorPos2.y + ), + cursorPos2.x == cursorPos.x + 20 + ); } @Test diff --git a/contrib/platform/test/com/sun/jna/platform/win32/Win32ServiceDemo.java b/contrib/platform/test/com/sun/jna/platform/win32/Win32ServiceDemo.java index e06b0aa94d..cdd0a42646 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/Win32ServiceDemo.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/Win32ServiceDemo.java @@ -120,7 +120,18 @@ public static boolean install() { } } } - invocation = String.format("java.exe -cp %s com.sun.jna.platform.win32.Win32ServiceDemo", sb.toString()); + + String JAVA_HOME = System.getenv("JAVA_HOME"); + String javaBinary = "java.exe"; + if(JAVA_HOME != null) { + javaBinary = "\"" + new File(JAVA_HOME, "\\bin\\java.exe").getAbsolutePath() + "\""; + } else { + javaBinary = "java.exe"; + } + + invocation = String.format("%s -Djna.nosys=true -cp %s com.sun.jna.platform.win32.Win32ServiceDemo", + javaBinary, + sb.toString()); System.out.println("Invocation: " + invocation); SERVICE_DESCRIPTION desc = new SERVICE_DESCRIPTION(); diff --git a/contrib/platform/test/com/sun/jna/platform/win32/WinspoolTest.java b/contrib/platform/test/com/sun/jna/platform/win32/WinspoolTest.java index 02e14c2625..54ec2009bf 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/WinspoolTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/WinspoolTest.java @@ -20,17 +20,29 @@ import com.sun.jna.platform.win32.Winspool.PRINTER_INFO_4; import com.sun.jna.ptr.IntByReference; -import junit.framework.TestCase; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import org.junit.Assume; +import org.junit.BeforeClass; +import org.junit.Test; /** * @author dblock[at]dblock[dot]org */ -public class WinspoolTest extends TestCase { +public class WinspoolTest { - public static void main(String[] args) { - junit.textui.TestRunner.run(WinspoolTest.class); + @BeforeClass + public static void setUp() throws Exception { + HANDLEByReference hbr = new HANDLEByReference(); + boolean result = Winspool.INSTANCE.OpenPrinter("Will not be found", hbr, null); + Assume.assumeFalse(result); + int error = Native.getLastError(); + Assume.assumeTrue("Print service not available", error != WinError.RPC_S_SERVER_UNAVAILABLE); } + @Test public void testEnumPrinters_4() { IntByReference pcbNeeded = new IntByReference(); IntByReference pcReturned = new IntByReference(); @@ -47,7 +59,8 @@ public void testEnumPrinters_4() { } } } - + + @Test public void testEnumPrinters_2() { IntByReference pcbNeeded = new IntByReference(); IntByReference pcReturned = new IntByReference(); @@ -64,7 +77,8 @@ public void testEnumPrinters_2() { } } } - + + @Test public void testEnumPrinters_1() { IntByReference pcbNeeded = new IntByReference(); IntByReference pcReturned = new IntByReference(); @@ -81,7 +95,8 @@ public void testEnumPrinters_1() { } } } - + + @Test public void testOpenPrinter() { HANDLEByReference hbr = new HANDLEByReference(); boolean result = Winspool.INSTANCE.OpenPrinter("1234567890A123", hbr, null); @@ -89,13 +104,15 @@ public void testOpenPrinter() { 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()); } - + + @Test 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()); } - + + @Test public void testCorrectDeclarationOfMembers() throws InstantiationException, IllegalAccessException { for(Class klass: Winspool.class.getDeclaredClasses()) { if(Structure.class.isAssignableFrom(klass)) { diff --git a/contrib/platform/test/com/sun/jna/platform/win32/WinspoolUtilTest.java b/contrib/platform/test/com/sun/jna/platform/win32/WinspoolUtilTest.java index 0d83c2388b..83b6efc41b 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/WinspoolUtilTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/WinspoolUtilTest.java @@ -12,45 +12,64 @@ */ package com.sun.jna.platform.win32; +import com.sun.jna.Native; import com.sun.jna.platform.win32.Winspool.PRINTER_INFO_1; import com.sun.jna.platform.win32.Winspool.PRINTER_INFO_4; -import junit.framework.TestCase; +import static junit.framework.TestCase.assertEquals; +import static junit.framework.TestCase.assertTrue; +import static junit.framework.TestCase.fail; +import org.junit.Assume; +import org.junit.BeforeClass; +import org.junit.Test; /** * @author dblock[at]dblock[dot]org */ -public class WinspoolUtilTest extends TestCase { +public class WinspoolUtilTest { public static void main(String[] args) { - junit.textui.TestRunner.run(WinspoolUtilTest.class); - for(PRINTER_INFO_1 printerInfo : WinspoolUtil.getPrinterInfo1()) { - System.out.println(printerInfo.pName + ": " + printerInfo.pDescription); + for (PRINTER_INFO_1 printerInfo : WinspoolUtil.getPrinterInfo1()) { + System.out.println(printerInfo.pName + ": " + printerInfo.pDescription); } - for(PRINTER_INFO_4 printerInfo : WinspoolUtil.getPrinterInfo4()) { - System.out.println(printerInfo.pPrinterName + " on " + printerInfo.pServerName); + for (PRINTER_INFO_4 printerInfo : WinspoolUtil.getPrinterInfo4()) { + System.out.println(printerInfo.pPrinterName + " on " + printerInfo.pServerName); } } - - public void testGetPrinterInfo1() { - assertTrue(WinspoolUtil.getPrinterInfo1().length >= 0); - } - - public void testGetPrinterInfo2() { - assertTrue(WinspoolUtil.getPrinterInfo2().length >= 0); - } - + + @BeforeClass + public static void setUp() throws Exception { + WinNT.HANDLEByReference hbr = new WinNT.HANDLEByReference(); + boolean result = Winspool.INSTANCE.OpenPrinter("Will not be found", hbr, null); + Assume.assumeFalse(result); + int error = Native.getLastError(); + Assume.assumeTrue("Print service not available", error != WinError.RPC_S_SERVER_UNAVAILABLE); + } + + @Test + public void testGetPrinterInfo1() { + assertTrue(WinspoolUtil.getPrinterInfo1().length >= 0); + } + + @Test + public void testGetPrinterInfo2() { + assertTrue(WinspoolUtil.getPrinterInfo2().length >= 0); + } + + @Test 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) { + Assume.assumeTrue("Print service not available", WinError.RPC_S_SERVER_UNAVAILABLE != e.getHR().intValue()); 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() { + @Test + public void testGetPrinterInfo4() { assertTrue(WinspoolUtil.getPrinterInfo4().length >= 0); } } diff --git a/native/dispatch.c b/native/dispatch.c index 072aed4176..6cee809fb1 100644 --- a/native/dispatch.c +++ b/native/dispatch.c @@ -653,7 +653,7 @@ dispatch(JNIEnv *env, void* func, jint flags, jobjectArray args, int err = GET_LAST_ERROR(); JNA_set_last_error(env, err); if ((flags & THROW_LAST_ERROR) && err) { - char emsg[MSG_SIZE]; + char emsg[MSG_SIZE - 3 /* literal characters */ - 10 /* max length of %d */]; snprintf(msg, sizeof(msg), "[%d] %s", err, STR_ERROR(err, emsg, sizeof(emsg))); throw_type = ELastError; throw_msg = msg; @@ -1896,7 +1896,7 @@ dispatch_direct(ffi_cif* cif, void* volatile resp, void** argp, void *cdata) { int err = GET_LAST_ERROR(); JNA_set_last_error(env, err); if (data->throw_last_error && err) { - char emsg[MSG_SIZE]; + char emsg[MSG_SIZE - 3 /* literal characters */ - 10 /* max length of %d */]; snprintf(msg, sizeof(msg), "[%d] %s", err, STR_ERROR(err, emsg, sizeof(emsg))); throw_type = ELastError; throw_msg = msg; @@ -3096,7 +3096,7 @@ Java_com_sun_jna_Native_getWindowHandle0(JNIEnv* UNUSED_JAWT(env), jclass UNUSED return -1; } if ((pJAWT_GetAWT = (void*)FIND_ENTRY(jawt_handle, METHOD_NAME)) == NULL) { - char msg[MSG_SIZE], buf[MSG_SIZE]; + char msg[MSG_SIZE], buf[MSG_SIZE - 31 /* literal characters */ - sizeof(METHOD_NAME)]; snprintf(msg, sizeof(msg), "Error looking up JAWT method %s: %s", METHOD_NAME, LOAD_ERROR(buf, sizeof(buf))); throwByName(env, EUnsatisfiedLink, msg); diff --git a/native/testlib.c b/native/testlib.c index 575cf010ae..609ed75ede 100644 --- a/native/testlib.c +++ b/native/testlib.c @@ -805,7 +805,7 @@ callCallbackWithStructByValue(TestStructureByValue (*func)(TestStructureByValue) EXPORT callback_t callCallbackWithCallback(cb_callback_t cb) { - return (*cb)((callback_t)cb); + return (*cb)((callback_t)(void*)cb); } static int32_t diff --git a/www/Contributing.md b/www/Contributing.md index c0735dc502..e934a8ed32 100644 --- a/www/Contributing.md +++ b/www/Contributing.md @@ -17,7 +17,8 @@ gcc, autotools (for libffi), ant (1.8+), a JDK (1.4+), and a few other typical command-line utilities available. Feel free to report any issues, we'll generally pull build fixes immediately. -Native bits are built by passing `-Dskip-native=false` to `ant`. It's +Native bits are built by invoking `ant native`. The build system is configured +to rebuild the native library automaticly if necessary. It's safe to skip the native build as long as your modifications are restricted to Java code.