8 messages in net.java.dev.jna.usersRe: [jna-users] Invoking WinINet Inte...
FromSent OnAttachments
Rogan DawesApr 28, 2008 9:39 am 
Albert StrasheimApr 28, 2008 1:04 pm 
Timothy WallApr 28, 2008 1:22 pm 
Rogan DawesApr 28, 2008 1:29 pm 
Rogan DawesApr 28, 2008 1:30 pm 
Timothy WallApr 28, 2008 1:45 pm 
Rogan DawesApr 28, 2008 3:21 pm 
Timothy WallApr 28, 2008 5:17 pm 
Actions with this message:
Paste this link in email or IM:
Paste this link in email or IM:
Atom feed for this thread
Paste this URL into your reader:
Subject:Re: [jna-users] Invoking WinINet InternetQueryOption/InternetSetOption?Actions...
From:Timothy Wall (twal@dev.java.net)
Date:Apr 28, 2008 5:17:03 pm
List:net.java.dev.jna.users

On Apr 28, 2008, at 6:22 PM, Rogan Dawes wrote:

public static class INTERNET_PER_CONN_OPTION_LIST extends Structure { public int dwSize; public WString pszConnection; public int dwOptionCount; public int dwOptionError; public INTERNET_PER_CONN_OPTION[] pOptions; }

Change pOptions to be Pointer, and use structs[0].getPointer() to initialize it.

Hi Timothy,

Thanks for your help. That change, along with completing the Union for INTERNET_PER_CONN_OPTION (it also has a FILETIME that I had omitted, thinking it wouldn't make any difference, but it did) allows me to execute the InternetQueryOption call successfuly, and get a "true" return value.

However, the INTERNET_PER_CONN_OPTION[] are never populated, other than by me. i.e. the JNI call makes no change to the values of the INTERNET_PER_CONN_OPTION elements.

Since the field is a Pointer, JNA can't tell that there's a structure array behind it and thus automatically invoke Structure.read() for each of them. You'll have to do that manually for as many of the structs in the array as the function says you get back.

I'm not sure whether I should be treating the "LPTSTR pszValue" as a Pointer or as a WString. This memory is allocated by the InternetQueryOption call, and I am therefore responsible for freeing it myself. Whichever approach I take, however, the value is still null.

If you have to free it later, you should use Pointer, otherwise the native pointer will be discarded and you won't have a reference to it. You can use Pointer.getString(0) to convert to String.

You may need to use Union.setType(Class) followed by Structure.read() in order to populate the union values; only primitive values will be read into union fields automatically, since attempting to read a String and other memory-based structures from memory can cause faults if it's not the actual union type.

Any suggestions are welcome.

Thanks

Rogan

Here is my current code:

------ snip ------ import com.sun.jna.Native; import com.sun.jna.Pointer; import com.sun.jna.Structure; import com.sun.jna.Union; import com.sun.jna.WString; import com.sun.jna.ptr.LongByReference; import com.sun.jna.win32.StdCallLibrary;

public class WindowsProxy {

public static void getCurrentProxyOptions() { INTERNET_PER_CONN_OPTION option = new INTERNET_PER_CONN_OPTION(); INTERNET_PER_CONN_OPTION[] options = (INTERNET_PER_CONN_OPTION[]) option.toArray(1); options[0].dwOption = INTERNET_PER_CONN_PROXY_SERVER;

INTERNET_PER_CONN_OPTION_LIST list = new INTERNET_PER_CONN_OPTION_LIST(); list.dwOptionCount = options.length; list.dwOptionError = 0; list.pOptions = options[0].getPointer(); list.dwSize = list.size(); LongByReference size = new LongByReference(list.size());

System.out.println("About to call InternetQueryOption");

if (!WinINet.INSTANCE.InternetQueryOptionW(null, INTERNET_OPTION_PER_CONNECTION_OPTION, list.getPointer(), size)) { throw new RuntimeException("error calling JNI"); }

System.out.println("Called InternetQueryOption");

options[0].value.setType(Pointer.class); System.out.println(options[0].value.pszValue.getString(0));

}

private static int INTERNET_PER_CONN_FLAGS = 1; private static int INTERNET_PER_CONN_PROXY_SERVER = 2; private static int INTERNET_PER_CONN_PROXY_BYPASS = 3; private static int INTERNET_PER_CONN_AUTOCONFIG_URL = 4; private static int INTERNET_PER_CONN_AUTODISCOVERY_FLAGS = 5;

private static int INTERNET_OPTION_PER_CONNECTION_OPTION = 75;

public static class INTERNET_PER_CONN_OPTION extends Structure { public int dwOption; public static class FILETIME extends Structure { public int dwLowDateTime; public int dwHighDateTime; } public static class Value extends Union { public int dwValue; public Pointer pszValue; public FILETIME ftValue; } public Value value; }

public static class INTERNET_PER_CONN_OPTION_LIST extends Structure { public int dwSize; public WString pszConnection; public int dwOptionCount; public int dwOptionError; public Pointer pOptions; }

private interface WinINet extends StdCallLibrary {

WinINet INSTANCE = (WinINet) Native.loadLibrary("wininet", WinINet.class);

boolean InternetQueryOptionW(Pointer unused, int dwOption, Pointer lpBuffer, LongByReference size);

}

public static void main(String[] args) { Native.setProtected(true); getCurrentProxyOptions(); } }