Skip to content

Commit

Permalink
[GITHUB-1286] Fix DBT Bindings and Win32WindowDemo
Browse files Browse the repository at this point in the history
- Ensure all structures defined in com.sun.jna.platform.win32.DBT can be
  instantiated
- Use correct mapping for DEV_BROADCAST_PORT#dbcp_name. And add accessor
  for the string value of that property. This is an API incompatible
  change, but the class could not be instantiated, so it is assumed,
  that it is a safe change
- Prevent potential out-of-bounds read in DEV_BROADCAST_DEVICEINTERFACE
- Make demo-nativewindowmsg.jar runnable

Closes: java-native-access#1286
  • Loading branch information
matthiasblaesing committed Dec 22, 2020
1 parent c44a545 commit d2b04e5
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 27 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Features

Bug Fixes
---------
* [#1286](https://github.com/java-native-access/jna/pull/1286): Fix bindings of `c.s.j.p.win32.DBT` - [@matthiasblaesing](https://github.com/matthiasblaesing).
* [#326](https://github.com/java-native-access/jna/issues/326): Fix loading library that re-uses pointers for different callbacks - [@fpapai](https://github.com/fpapai).
* [#1244](https://github.com/java-native-access/jna/issues/1244): Fix building on GCC 10 - [@matthiasblaesing](https://github.com/matthiasblaesing).
* [#1252](https://github.com/java-native-access/jna/issues/1252): - Fix bindings of `CTL_ENTRY#getRgAttribute`, `CTL_INFO#getRgCTLEntry`, `CTL_INFO#getRgExtension`, `CERT_EXTENSIONS#getRgExtension`, `CERT_INFO#getRgExtension`, `CRL_INFO#getRgCRLEntry`, `CRL_INFO#getRgExtension`, `CRL_ENTRY#getRgExtension`. Add bindings for `CertEnumCertificatesInStore`, `CertEnumCTLsInStore`, `CertEnumCRLsInStore` and `CryptQueryObject` in `c.s.j.p.win32.Crypt32`.<br> *WARNING:* The signatures for `CTL_INFO#getRgCTLEntry` and `CTL_INFO#getRgExtension` were changed - as the original signatures were obviously wrong and read the wrong attributes, it is not considered an API break - [@matthiasblaesing](https://github.com/matthiasblaesing).
Expand Down
13 changes: 6 additions & 7 deletions contrib/native_window_msg/build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@
<project name="jnacontrib.native_window_msg" default="jar" basedir=".">
<description>Builds, tests, and runs the project jnacontrib.native_window_msg.</description>
<!-- Locations -->
<property name="src" location="./src"/>
<property name="build" location="build"/>
<property name="jna-dist" location="../../dist"/>

<property name="classes" location="${build}/classes"/>
<property name="jar" location="${build}/demo-nativewindowmsg.jar"/>
<property name="src" location="./src"/>
<property name="build" location="build"/>
<property name="jna-dist" location="../../dist"/>
<property name="classes" location="${build}/classes"/>
<property name="jar" location="${build}/demo-nativewindowmsg.jar"/>
<property name="file.reference.jna.jar" location="../../build/jna.jar"/>
<property name="main-class" value="com.sun.jna.platform.win32.Win32WindowDemo.java" />
<property name="main-class" value="com.sun.jna.platform.win32.Win32WindowDemo" />

<path id="classpath">
<fileset file="${file.reference.jna.jar}"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public class Win32WindowDemo implements WindowProc {
*/
public Win32WindowDemo() {
// define new window class
String windowClass = new String("MyWindowClass");
String windowClass = "MyWindowClass";
HMODULE hInst = Kernel32.INSTANCE.GetModuleHandle("");

WNDCLASSEX wClass = new WNDCLASSEX();
Expand Down Expand Up @@ -123,6 +123,7 @@ public Win32WindowDemo() {
* .win32.WinDef.HWND, int, com.sun.jna.platform.win32.WinDef.WPARAM,
* com.sun.jna.platform.win32.WinDef.LPARAM)
*/
@Override
public LRESULT callback(HWND hwnd, int uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case WinUser.WM_CREATE: {
Expand Down Expand Up @@ -152,7 +153,7 @@ public LRESULT callback(HWND hwnd, int uMsg, WPARAM wParam, LPARAM lParam) {
*
* @return the last error
*/
public int getLastError() {
public final int getLastError() {
int rc = Kernel32.INSTANCE.GetLastError();

if (rc != 0)
Expand Down Expand Up @@ -294,9 +295,8 @@ protected LRESULT onDeviceChangeArrivalOrRemoveComplete(LPARAM lParam, String ac
DEV_BROADCAST_DEVICEINTERFACE bdif = new DEV_BROADCAST_DEVICEINTERFACE(bhdr.getPointer());
System.out.println("BROADCAST_DEVICEINTERFACE: " + action);
System.out.println("dbcc_devicetype: " + bdif.dbcc_devicetype);
System.out.println("dbcc_name: " + bdif.getDbcc_name());
System.out.println("dbcc_classguid: "
+ bdif.dbcc_classguid.toGuidString());
System.out.println("dbcc_name: " + bdif.getDbcc_name());
System.out.println("dbcc_classguid: " + bdif.dbcc_classguid.toGuidString());
break;
}
case DBT.DBT_DEVTYP_HANDLE: {
Expand All @@ -314,7 +314,9 @@ protected LRESULT onDeviceChangeArrivalOrRemoveComplete(LPARAM lParam, String ac
case DBT.DBT_DEVTYP_PORT: {
// see http://msdn.microsoft.com/en-us/library/windows/desktop/aa363248.aspx
DEV_BROADCAST_PORT bpt = new DEV_BROADCAST_PORT(bhdr.getPointer());
System.out.println("BROADCAST_PORT: " + action);
System.out.println("BROADCAST_PORT: " + action);
System.out.println("dbcp_devicetype: " + bpt.dbcp_devicetype);
System.out.println("dbcp_name: " + bpt.getDbcpName());
break;
}
case DBT.DBT_DEVTYP_VOLUME: {
Expand Down Expand Up @@ -380,6 +382,7 @@ protected void onCreate(WPARAM wParam, LPARAM lParam) {
* @param args
* the arguments
*/
@SuppressWarnings("ResultOfObjectAllocationIgnored")
public static void main(String[] args) {
new Win32WindowDemo();
}
Expand Down
57 changes: 43 additions & 14 deletions contrib/platform/src/com/sun/jna/platform/win32/DBT.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 All @@ -33,6 +31,9 @@
import com.sun.jna.platform.win32.WinDef.LONG;
import com.sun.jna.platform.win32.WinNT.HANDLE;
import com.sun.jna.platform.win32.WinUser.HDEVNOTIFY;
import com.sun.jna.win32.W32APITypeMapper;
import java.nio.charset.StandardCharsets;
import java.util.logging.Logger;

/**
* Based on dbt.h (various types)
Expand Down Expand Up @@ -96,7 +97,7 @@ public interface DBT {
@FieldOrder({"dbch_size", "dbch_devicetype", "dbch_reserved"})
public class DEV_BROADCAST_HDR extends Structure {
/** The dbch_size. */
public int dbch_size = size();
public int dbch_size;

/** The dbch_devicetype. */
public int dbch_devicetype;
Expand Down Expand Up @@ -160,7 +161,7 @@ public DEV_BROADCAST_HDR(Pointer memory) {
@FieldOrder({"dbco_size", "dbco_devicetype", "dbco_reserved", "dbco_identifier", "dbco_suppfunc"})
public class DEV_BROADCAST_OEM extends Structure {
/** The dbco_size. */
public int dbco_size = size();
public int dbco_size;

/** The dbco_devicetype. */
public int dbco_devicetype;
Expand Down Expand Up @@ -199,7 +200,7 @@ public DEV_BROADCAST_OEM(Pointer memory) {
@FieldOrder({"dbcd_size", "dbcd_devicetype", "dbcd_reserved", "dbcd_devnode"})
public class DEV_BROADCAST_DEVNODE extends Structure {
/** The dbcd_size. */
public int dbcd_size = size();
public int dbcd_size;

/** The dbcd_devicetype. */
public int dbcd_devicetype;
Expand Down Expand Up @@ -235,7 +236,7 @@ public DEV_BROADCAST_DEVNODE(Pointer memory) {
@FieldOrder({"dbcv_size", "dbcv_devicetype", "dbcv_reserved", "dbcv_unitmask", "dbcv_flags"})
public class DEV_BROADCAST_VOLUME extends Structure {
/** The dbcv_size. */
public int dbcv_size = size();
public int dbcv_size;

/** The dbcv_devicetype. */
public int dbcv_devicetype;
Expand Down Expand Up @@ -280,7 +281,7 @@ public DEV_BROADCAST_VOLUME(Pointer memory) {
@FieldOrder({"dbcp_size", "dbcp_devicetype", "dbcp_reserved", "dbcp_name"})
public class DEV_BROADCAST_PORT extends Structure {
/** The dbcp_size. */
public int dbcp_size = size();
public int dbcp_size;

/** The dbcp_devicetype. */
public int dbcp_devicetype;
Expand All @@ -289,7 +290,7 @@ public class DEV_BROADCAST_PORT extends Structure {
public int dbcp_reserved;

/** The dbcp_name. */
public char[] dbcp_name = new char[1];
public byte[] dbcp_name = new byte[1];

/**
* Instantiates a new dev broadcast port.
Expand All @@ -308,6 +309,26 @@ public DEV_BROADCAST_PORT(Pointer memory) {
super(memory);
read();
}

@Override
public void read() {
int size = getPointer().getInt(0); // Read dbcp_size (first field in structure)
this.dbcp_name = new byte[size - this.fieldOffset("dbcp_name")];
super.read();
}

/**
* Gets the dbcc_name.
*
* @return the dbcp_name
*/
public String getDbcpName() {
if(W32APITypeMapper.DEFAULT == W32APITypeMapper.ASCII) {
return Native.toString(this.dbcp_name);
} else {
return new String(this.dbcp_name, StandardCharsets.UTF_16LE);
}
}
}

/**
Expand All @@ -317,7 +338,7 @@ public DEV_BROADCAST_PORT(Pointer memory) {
"dbcn_reserved", "dbcn_resource", "dbcn_flags"})
public class DEV_BROADCAST_NET extends Structure {
/** The dbcn_size. */
public int dbcn_size = size();
public int dbcn_size;

/** The dbcn_devicetype. */
public int dbcn_devicetype;
Expand Down Expand Up @@ -396,11 +417,19 @@ public DEV_BROADCAST_DEVICEINTERFACE(long pointer) {
*/
public DEV_BROADCAST_DEVICEINTERFACE(Pointer memory) {
super(memory);
this.dbcc_size = (Integer) this.readField("dbcc_size");
read();
}

@Override
public void read() {
if(W32APITypeMapper.DEFAULT == W32APITypeMapper.ASCII) {
Logger.getLogger(DBT.class.getName()).warning("DEV_BROADCAST_DEVICEINTERFACE must not be used with w32.ascii = true!");
}
int size = getPointer().getInt(0); // Read dbcc_size (first field in structure)
// figure out how long dbcc_name should be based on the size
int len = 1 + this.dbcc_size - size();
int len = (size - this.fieldOffset("dbcc_name")) / Native.WCHAR_SIZE;
this.dbcc_name = new char[len];
read();
super.read();
}

/**
Expand All @@ -420,7 +449,7 @@ public String getDbcc_name() {
"dbch_hdevnotify", "dbch_eventguid", "dbch_nameoffset", "dbch_data"})
public class DEV_BROADCAST_HANDLE extends Structure {
/** The dbch_size. */
public int dbch_size = size();
public int dbch_size;

/** The dbch_devicetype. */
public int dbch_devicetype;
Expand All @@ -441,7 +470,7 @@ public class DEV_BROADCAST_HANDLE extends Structure {
public LONG dbch_nameoffset;

/** The dbch_data. */
public byte[] dbch_data;
public byte[] dbch_data = new byte[1];

/**
* Instantiates a new dev broadcast handle.
Expand Down
50 changes: 50 additions & 0 deletions contrib/platform/test/com/sun/jna/platform/win32/DBTTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/* Copyright (c) 2020 Matthias Bläsing
*
* The contents of this file is dual-licensed under 2
* alternative Open Source/Free licenses: LGPL 2.1 or later and
* Apache License 2.0. (starting with JNA version 4.0.0).
*
* You can freely decide which license you want to apply to
* the project.
*
* You may obtain a copy of the LGPL License at:
*
* http://www.gnu.org/licenses/licenses.html
*
* A copy is also included in the downloadable source code package
* containing JNA, in file "LGPL2.1".
*
* You may obtain a copy of the Apache License at:
*
* http://www.apache.org/licenses/
*
* A copy is also included in the downloadable source code package
* containing JNA, in file "AL2.0".
*/
package com.sun.jna.platform.win32;

import com.sun.jna.Structure;
import com.sun.jna.platform.win32.DBT.DEV_BROADCAST_DEVICEINTERFACE;
import com.sun.jna.platform.win32.DBT.DEV_BROADCAST_DEVNODE;
import com.sun.jna.platform.win32.DBT.DEV_BROADCAST_HANDLE;
import com.sun.jna.platform.win32.DBT.DEV_BROADCAST_HDR;
import com.sun.jna.platform.win32.DBT.DEV_BROADCAST_NET;
import com.sun.jna.platform.win32.DBT.DEV_BROADCAST_OEM;
import com.sun.jna.platform.win32.DBT.DEV_BROADCAST_PORT;
import com.sun.jna.platform.win32.DBT.DEV_BROADCAST_VOLUME;
import org.junit.Test;

public class DBTTest {
@Test
public void testInstantiation() {
// Ensure, that the structures can be instantiated
Structure.newInstance(DEV_BROADCAST_DEVICEINTERFACE.class);
Structure.newInstance(DEV_BROADCAST_DEVNODE.class);
Structure.newInstance(DEV_BROADCAST_HANDLE.class);
Structure.newInstance(DEV_BROADCAST_HDR.class);
Structure.newInstance(DEV_BROADCAST_NET.class);
Structure.newInstance(DEV_BROADCAST_OEM.class);
Structure.newInstance(DEV_BROADCAST_PORT.class);
Structure.newInstance(DEV_BROADCAST_VOLUME.class);
}
}

0 comments on commit d2b04e5

Please sign in to comment.