Skip to content

Commit

Permalink
Merge pull request #992 from matthiasblaesing/appveyor
Browse files Browse the repository at this point in the history
Enhance stability of tests and prepare for inclusion of appveyor
  • Loading branch information
matthiasblaesing authored Aug 1, 2018
2 parents c7419af + c742e78 commit 4441b3e
Show file tree
Hide file tree
Showing 24 changed files with 461 additions and 186 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
20 changes: 20 additions & 0 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -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
8 changes: 6 additions & 2 deletions contrib/platform/src/com/sun/jna/platform/win32/Pdh.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down
203 changes: 116 additions & 87 deletions contrib/platform/src/com/sun/jna/platform/win32/PdhUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand All @@ -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<String> PdhEnumObjectItemCounters(String szDataSource, String szMachineName, String szObjectName,
public static PdhEnumObjectItems PdhEnumObjectItems(String szDataSource, String szMachineName, String szObjectName,
int dwDetailLevel) {
List<String> counters = new ArrayList<String>();
List<String> instances = new ArrayList<String>();

// 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<String> PdhEnumObjectItemInstances(String szDataSource, String szMachineName,
String szObjectName, int dwDetailLevel) {
List<String> instances = new ArrayList<String>();
public static class PdhEnumObjectItems {
private final List<String> counters;
private final List<String> 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<String> counters, List<String> 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<String> 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<String> 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<String> copyAndEmptyListForNullList (List<String> inputList) {
if(inputList == null) {
return new ArrayList<String>();
} else {
s = mszInstanceList.getWideString(offset);
}
// list ends with double null
if (s.isEmpty()) {
break;
return new ArrayList<String>(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;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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: {&lt;UID&gt;}
*/
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;
}
}
Loading

0 comments on commit 4441b3e

Please sign in to comment.