• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

JNA call to kernel32.dll

 
Ranch Hand
Posts: 50
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Howdy,

I'm trying to make a function call using JNA to GetVolumeInformation as described here, http://msdn2.microsoft.com/en-us/library/aa364993.aspx. I've been able to successfully call other functions already, GetSystemTime & GetLogicalDrives, so my setup seems to be in order.

The example calls to GetVolumeInformation I've found online are all in other languages, so I think my problem is that my method signature is wrong and hence the function is not found.

Here's one example I found and tried to adapt as Java:



I changed the uint to be int and tried returning a long as opposed to a Boolean, but no joy.

Can anyone suggest how to construct a valid java method to make a call to this function?

I know I could use JNI for this but have no c++ experience and found the various tutorials fall short at the compilation stage, for me.

Thanks
 
billo bailey
Ranch Hand
Posts: 50
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
hooray progress, boooo more problems

So it seems the call is now working, however it results in a access violation problem, here's the method sig:



and here's the error:





Anyone any suggestions?

Thanks
 
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Use char[] or byte[] for character buffers, not StringBuilder. Follow the recommended type mappings given in http://jna.dev.java.net and the JNA JavaDoc overview.
 
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This worked for me, sorry the code is not very clean, but it works :-)

SAMPLE USAGE:
VolumeInformation info = VolumeInformation.createVolumeInformation("c:\\");
System.out.println(info.getDiskLabel());
System.out.println(info.getDiskSerial());
System.out.println(info.getFileSystem());

FILE VolumeInformation.java

import java.io.File;

public abstract class VolumeInformation {


public static VolumeInformation createVolumeInformation(String path) {
File pathFile = new File(path);
return createVolumeInformation(pathFile);
}

public static VolumeInformation createVolumeInformation(File pathFile) {
//return new VolumeInformation_win_cmdVol(pathFile);
return new VolumeInformation_win_jni(pathFile);
}

/**
* Returns the serial id of the disk containing
* the specified path
* @return
*/
public abstract String getDiskSerial();

/**
* Returns the label of the disk containing
* the specified path
* @return
*/
public abstract String getDiskLabel();

public abstract String getFileSystem();

}

FILE VolumeInformation_win_jni.java

import java.io.File;
import java.io.IOException;
import java.nio.CharBuffer;
import com.sun.jna.ptr.LongByReference;

class VolumeInformation_win_jni extends VolumeInformation {

private String diskSerial;
private String diskLabel;
private String fileSystem;

public VolumeInformation_win_jni(String path) {
this(new File(path));
}


/**
* @param pathFile
*/
public VolumeInformation_win_jni(File pathFile) {
String driveName;
try {
driveName = pathFile.getCanonicalPath().substring(0, 2) + "\\";
} catch(IOException e) {
throw new RuntimeException(e);
}

//byte[] lpRootPathName = new byte[4];
//for (int i=0; i<3; i++) {
//lpRootPathName[i] = (byte)(((byte)driveName.charAt(i)));
//}
//lpRootPathName[3] = '\0';
//char[] lpRootPathName_chars0 = driveName.toCharArray();
char[] lpRootPathName_chars = new char[4];
for (int i=0; i<3; i++) {
lpRootPathName_chars[i] = driveName.charAt(i);
}
lpRootPathName_chars[3] = '\0';
int nVolumeNameSize = 256;
//String lpRootPathName_string = driveName;
//ByteBuffer lpVolumeNameBuffer_byte = ByteBuffer.allocate(nVolumeNameSize);
CharBuffer lpVolumeNameBuffer_char = CharBuffer.allocate(nVolumeNameSize);
LongByReference lpVolumeSerialNumber = new LongByReference();
LongByReference lpMaximumComponentLength = new LongByReference();
LongByReference lpFileSystemFlags = new LongByReference();
int nFileSystemNameSize = 256;
//ByteBuffer lpFileSystemNameBuffer_byte = ByteBuffer.allocate(nFileSystemNameSize);
CharBuffer lpFileSystemNameBuffer_char = CharBuffer.allocate(nFileSystemNameSize);

//boolean result = MyKernel32.INSTANCE.GetVolumeInformationA(
//lpRootPathName_string,
//lpVolumeNameBuffer_byte,
//nVolumeNameSize,
//lpVolumeSerialNumber,
//lpMaximumComponentLength,
//lpFileSystemFlags,
//lpFileSystemNameBuffer_byte,
//nFileSystemNameSize);
//int err = MyKernel32.INSTANCE.GetLastError();
//this.diskLabel = lpVolumeNameBuffer_byte.toString();
//this.diskSerial = Long.toHexString(lpVolumeSerialNumber.getValue());
//this.fileSystem = lpFileSystemNameBuffer_byte.toString();

boolean result2 = MyKernel32.INSTANCE.GetVolumeInformationW(
lpRootPathName_chars,
lpVolumeNameBuffer_char,
nVolumeNameSize,
lpVolumeSerialNumber,
lpMaximumComponentLength,
lpFileSystemFlags,
lpFileSystemNameBuffer_char,
nFileSystemNameSize);
if (!result2) {
int err2 = MyKernel32.INSTANCE.GetLastError();
throw new RuntimeException("W32Api call to GetVolumeInformationW returned err code " + err2);
}
this.diskLabel = charString2String(lpVolumeNameBuffer_char);
this.fileSystem = charString2String(lpFileSystemNameBuffer_char);
this.diskSerial = Long.toHexString(lpVolumeSerialNumber.getValue());

}

/**
* Returns the serial id of the disk containing
* the specified path
* @return
*/
@Override
public String getDiskSerial() {
return diskSerial;
}

/**
* Returns the label of the disk containing
* the specified path
* @return
*/
@Override
public String getDiskLabel() {
return diskLabel;
}

@Override
public String getFileSystem() {
return fileSystem;
}

private String charString2String(CharBuffer buf) {
char[] chars = buf.array();
int i;
for (i=0; i<chars.length; i++) {
if (chars[i]=='\0') break;
}
return new String(chars,0,i);
}
}
 
david lastovicka
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The code above requires jna.jar as well as examples.jar to be included in the project
 
david lastovicka
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I forgot one class:

FILE MyKernel32.java

import java.nio.ByteBuffer;
import java.nio.CharBuffer;

import com.sun.jna.Native;
import com.sun.jna.examples.win32.Kernel32;
import com.sun.jna.ptr.LongByReference;

interface MyKernel32 extends Kernel32 {

boolean GetVolumeInformationW(
char[] lpRootPathName,
CharBuffer lpVolumeNameBuffer,
int nVolumeNameSize,
LongByReference lpVolumeSerialNumber,
LongByReference lpMaximumComponentLength,
LongByReference lpFileSystemFlags,
CharBuffer lpFileSystemNameBuffer,
int nFileSystemNameSize
);

boolean GetVolumeInformationA(
String lpRootPathName,
ByteBuffer lpVolumeNameBuffer,
int nVolumeNameSize,
LongByReference lpVolumeSerialNumber,
LongByReference lpMaximumComponentLength,
LongByReference lpFileSystemFlags,
ByteBuffer lpFileSystemNameBuffer,
int nFileSystemNameSize
);

MyKernel32 INSTANCE = (MyKernel32)Native.loadLibrary("kernel32", MyKernel32.class);

}
 
We cannot change unless we survive, but we will not survive unless we change. Evolving tiny ad:
a bit of art, as a gift, that will fit in a stocking
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic