cyberoblivion
cyberoblivion

Reputation: 719

LastErrorException: [1413] Invalid index from JNA on 64Bit windows

I have a simple program using java native access which works perfectly on 32 bit java but does not work on 64 bit jvm.

The program output on 64 bit os and jvm is as follows

Day of the Week 4
Year :  2013
Processor Type : 8664
System Metrics : 960
Setting HWPointer
Getting current wnd proc ptr
Exception in thread "main" com.sun.jna.LastErrorException: [1413] Invalid index.
    at com.sun.jna.Native.invokeLong(Native Method)
    at com.sun.jna.Function.invoke(Function.java:386)
    at com.sun.jna.Function.invoke(Function.java:315)
    at com.sun.jna.Library$Handler.invoke(Library.java:212)
    at com.sun.proxy.$Proxy2.GetWindowLongW(Unknown Source)
    at SutdownJna.main(SutdownJna.java:71)

This is the code.

    public class SutdownJna {

    public interface User33 extends User32 {

//        static int GWL_WNDPROC = -4;
        User33 INSTANCE = (User33) Native.loadLibrary("user32", User33.class,
                W32APIOptions.DEFAULT_OPTIONS);

        interface WNDPROC extends StdCallLibrary.StdCallCallback {

            LRESULT callback(HWND hWnd, int uMsg, WPARAM uParam, LPARAM lParam);
        }

        LONG_PTR GetWindowLongW(HWND hWnd, int nIndex) throws LastErrorException;

        LRESULT CallWindowProcW(LONG_PTR proc, HWND hWnd, int uMsg, WPARAM uParam, LPARAM lParam);

        LONG_PTR SetWindowLongW(HWND hWnd, int nIndex, User33.WNDPROC wndProc);
    }
    public static final int WM_QUERYENDSESSION = 0x11;

    public static void main(String[] args) {
        User33.WNDPROC wndProcCallbackListener = null;

        final JFrame frame = new JFrame("Shutdown Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);


        Kernel32 INSTANCE = (Kernel32) Native
                .loadLibrary("Kernel32", Kernel32.class);

        SYSTEMTIME time = new SYSTEMTIME();
        INSTANCE.GetSystemTime(time);
        System.out.println("Day of the Week " + time.wDayOfWeek);
        System.out.println("Year :  " + time.wYear);

        SYSTEM_INFO systeminfo = new SYSTEM_INFO();
        INSTANCE.GetSystemInfo(systeminfo);
        System.out.println("Processor Type : " + systeminfo.dwProcessorType);
        System.out.println("System Metrics : " + User32.INSTANCE.GetSystemMetrics(1));
        HWND hwnd = new HWND();
        System.out.println("Setting HWPointer");
        hwnd.setPointer(Native.getComponentPointer(frame));
        System.out.println("Getting current wnd proc ptr");
        final LONG_PTR prevWndProc = User33.INSTANCE.GetWindowLongW(hwnd, User33.GWL_WNDPROC);
        System.out.println("Creating new wnd proc ptr");
        User33.WNDPROC proc = new User33.WNDPROC() {
            public LRESULT callback(HWND wnd, int msg, WPARAM param, LPARAM param2) {
                System.out.println("Received msg : " + msg);
                if (msg != WM_QUERYENDSESSION) {
                    return User33.INSTANCE.CallWindowProcW(prevWndProc, wnd, msg, param, param2);
                } else {
                    return new LRESULT(0);
                }
            }
        };

        System.out.println("Setting new Proc Handler " + proc);
        User33.INSTANCE.SetWindowLongW(hwnd, User33.GWL_WNDPROC, proc);

    }
}

The tests wereper formed on windows 7 32bit and windows 7 64 bit.

Upvotes: 0

Views: 587

Answers (1)

technomage
technomage

Reputation: 10069

See the docs for GetWindowLongPtr. You're retrieving a pointer value, which will be 64 bits on a 64-bit system. It's not clear whether GetWindowLongPtr is a macro or a function on 32-bit (you'll get an UnsatisfiedLinkError if it's only a macro).

Upvotes: 1

Related Questions