Skip to content

Commit 3c4e69c

Browse files
committed
Windows: more composite device handling improvements
1 parent 09fe484 commit 3c4e69c

File tree

3 files changed

+26
-25
lines changed

3 files changed

+26
-25
lines changed

java-does-usb/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>net.codecrete.usb</groupId>
88
<artifactId>java-does-usb</artifactId>
9-
<version>0.6.0</version>
9+
<version>0.6.1-SNAPSHOT</version>
1010

1111
<properties>
1212
<maven.compiler.source>21</maven.compiler.source>

java-does-usb/src/main/java/net/codecrete/usb/windows/WindowsUSBDevice.java

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,13 @@ public class WindowsUSBDevice extends USBDeviceImpl {
4949
private static final int SUCCESS = 2;
5050

5151
private final WindowsAsyncTask asyncTask;
52+
/**
53+
* Indicates if the device is a composite device
54+
*/
55+
private final boolean isComposite;
56+
5257
private List<InterfaceHandle> interfaceHandles;
58+
5359
// device paths by interface number (first interface of function)
5460
private Map<Integer, String> devicePaths;
5561

@@ -59,9 +65,12 @@ public class WindowsUSBDevice extends USBDeviceImpl {
5965
*/
6066
private boolean showAsOpen;
6167

62-
WindowsUSBDevice(String devicePath, int vendorId, int productId, MemorySegment configDesc) {
68+
WindowsUSBDevice(String devicePath, int vendorId, int productId, MemorySegment configDesc, boolean isComposite) {
6369
super(devicePath, vendorId, productId);
6470
asyncTask = WindowsAsyncTask.INSTANCE;
71+
this.isComposite = isComposite;
72+
if (isComposite)
73+
devicePaths = new HashMap<>();
6574
readDescription(configDesc);
6675
}
6776

@@ -238,14 +247,7 @@ public synchronized void releaseInterface(int interfaceNumber) {
238247
WinUSB.WinUsb_Free(firstIntfHandle.winusbHandle);
239248
firstIntfHandle.winusbHandle = null;
240249

241-
var path = (String)getUniqueId();
242-
if (firstIntfHandle.interfaceNumber != 0) {
243-
if (devicePaths != null)
244-
path = devicePaths.get(firstIntfHandle.interfaceNumber);
245-
else
246-
path = null;
247-
}
248-
LOG.log(DEBUG, "closing device {0}", path);
250+
LOG.log(DEBUG, "closing device {0}", getCachedInterfaceDevicePath(interfaceNumber));
249251

250252
Kernel32.CloseHandle(firstIntfHandle.deviceHandle);
251253
firstIntfHandle.deviceHandle = null;
@@ -516,20 +518,13 @@ private InterfaceHandle findControlTransferInterface(USBControlTransfer setup) {
516518
}
517519

518520
private String getInterfaceDevicePath(int interfaceNumber) {
519-
var parentDevicePath = (String) getUniqueId(); // device path is id
520-
if (interfaceNumber == 0)
521-
return parentDevicePath;
522-
523-
if (devicePaths != null) {
524-
var devicePath = devicePaths.get(interfaceNumber);
525-
if (devicePath != null)
526-
return devicePath;
527-
}
521+
var devicePath = getCachedInterfaceDevicePath(interfaceNumber);
522+
if (devicePath != null)
523+
return devicePath;
528524

529-
try (var deviceInfoSet = DeviceInfoSet.ofPath(parentDevicePath)) {
530-
if (!deviceInfoSet.isCompositeDevice())
531-
throwException("internal error: interface belongs to a composite function but device is not composite");
525+
var parentDevicePath = (String) getUniqueId();
532526

527+
try (var deviceInfoSet = DeviceInfoSet.ofPath(parentDevicePath)) {
533528
var childrenInstanceIDs = deviceInfoSet.getStringListProperty(Children);
534529
if (childrenInstanceIDs == null) {
535530
LOG.log(DEBUG, "missing children instance IDs for device {0}", parentDevicePath);
@@ -551,6 +546,12 @@ private String getInterfaceDevicePath(int interfaceNumber) {
551546
return null; // retry later
552547
}
553548

549+
private String getCachedInterfaceDevicePath(int interfaceNumber) {
550+
if (!isComposite)
551+
return (String) getUniqueId();
552+
return devicePaths.get(interfaceNumber);
553+
}
554+
554555
private int fetchChildDevicePath(String instanceId, int interfaceNumber) {
555556
try (var deviceInfoSet = DeviceInfoSet.ofInstance(instanceId)) {
556557

java-does-usb/src/main/java/net/codecrete/usb/windows/WindowsUSBDeviceRegistry.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ private USBDevice createDeviceFromDeviceInfo(DeviceInfoSet deviceInfoSet, String
174174
hubHandles.put(hubPath, hubHandle);
175175
}
176176

177-
return createDevice(devicePath, hubHandle, usbPortNum);
177+
return createDevice(devicePath, deviceInfoSet.isCompositeDevice(), hubHandle, usbPortNum);
178178
}
179179
}
180180

@@ -186,7 +186,7 @@ private USBDevice createDeviceFromDeviceInfo(DeviceInfoSet deviceInfoSet, String
186186
* @param usbPortNum the USB port number
187187
* @return the {@code USBDevice} instance
188188
*/
189-
private USBDevice createDevice(String devicePath, MemorySegment hubHandle, int usbPortNum) {
189+
private USBDevice createDevice(String devicePath, boolean isComposite, MemorySegment hubHandle, int usbPortNum) {
190190

191191
try (var arena = Arena.ofConfined()) {
192192

@@ -209,7 +209,7 @@ private USBDevice createDevice(String devicePath, MemorySegment hubHandle, int u
209209
var configDesc = getDescriptor(hubHandle, usbPortNum, CONFIGURATION_DESCRIPTOR_TYPE, 0, (short) 0, arena);
210210

211211
// create new device
212-
var device = new WindowsUSBDevice(devicePath, vendorId, productId, configDesc);
212+
var device = new WindowsUSBDevice(devicePath, vendorId, productId, configDesc, isComposite);
213213
device.setFromDeviceDescriptor(descriptorSegment);
214214
device.setProductString(descriptorSegment, index -> getStringDescriptor(hubHandle, usbPortNum, index));
215215

0 commit comments

Comments
 (0)