Skip to content

Commit

Permalink
Merge pull request #2 from java-native-access/master
Browse files Browse the repository at this point in the history
Update fork
  • Loading branch information
CamW authored Aug 12, 2018
2 parents f062487 + 8d7efcc commit 3e53e1f
Show file tree
Hide file tree
Showing 31 changed files with 471 additions and 193 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
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
---------
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -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)
========================
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
2 changes: 1 addition & 1 deletion build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
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 @@ -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 {
}

Expand Down
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 3e53e1f

Please sign in to comment.