JNA call RegisterDeviceNotification fails with err

2019-09-15 22:20发布

问题:

I am attempting to register for notifications on USB device arrival and device remove complete events from a java swing application.

I have successfully called

SetWindowLong(hWnd, MyUser32.GWLP_WNDPROC, listener);

to register a listener and I am getting notifications of type WM_DEVICECHANGE. So far so good.

Now I want to call RegisterDeviceNotification to ensure that I am notified of device arrival and remove complete events. Here is what I have tried:

HWND hWnd = new HWND();
hWnd.setPointer(Native.getWindowPointer(frame));
DEV_BROADCAST_DEVICEINTERFACE filter = new DEV_BROADCAST_DEVICEINTERFACE();
filter.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE;       
filter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
filter.dbcc_name = new char[1];
filter.dbcc_reserved = new DWORD(0);
filter.dbcc_size = new DWORD(filter.size());
filter.dbcc_size = new DWORD(filter.size());

long retVal = MyUser32.MYINSTANCE.RegisterDeviceNotification(new HANDLE(hWnd.getPointer()), filter.getPointer(), DEVICE_NOTIFY_WINDOW_HANDLE);

if (retVal != 0) {
    System.out.println("Error registering for usb: " + Native.getLastError());
}

My JNA declarations are:

public long RegisterDeviceNotification(HANDLE hRecipient, Pointer NotificationFilter, DWORD Flags);

public static class DEV_BROADCAST_DEVICEINTERFACE extends Structure {
      public DWORD dbcc_size;
      public DWORD dbcc_devicetype;
      public DWORD dbcc_reserved;
      public GUID  dbcc_classguid;
      public char[] dbcc_name;
}

public static final GUID GUID_DEVINTERFACE_USB_DEVICE = new GUID(new byte[] {
        (byte)0xA5, (byte)0xDC, (byte)0xBF, 0x10, 0x65, 0x30, 0x11, (byte)0xD2, (byte)0x90, 0x1F, 0x00, (byte)0xC0, 0x4F, (byte)0xB9, 0x51, (byte)0xED          
});

I am always receiving an error 1066. Any help would be appreciated. If more information is required let me know and I can include it.

回答1:

Declaring RegisterDeviceNotification to return long was causing the problem. According to the JNA FAQ, JNA FAQ

Actually, no one ever asks this question, but they really need the answer. Do not use Java long!

On Windows, you can use a Java int, since the native long type is always 32 bits. On any other platform, the type may be 32 or 64 bits, so you should use the NativeLong type to ensure the proper size is used.



标签: java winapi jna