usb 2.17.0 → 2.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +14 -0
  3. package/binding.gyp +2 -9
  4. package/dist/usb/bindings.d.ts +27 -2
  5. package/dist/usb/bindings.js.map +1 -1
  6. package/dist/usb/index.d.ts +0 -29
  7. package/dist/usb/index.js +4 -18
  8. package/dist/usb/index.js.map +1 -1
  9. package/libusb/.clang-tidy +5 -3
  10. package/libusb/.private/ci-build.sh +5 -1
  11. package/libusb/AUTHORS +14 -0
  12. package/libusb/ChangeLog +15 -2
  13. package/libusb/README +8 -5
  14. package/libusb/Xcode/libusb.xcodeproj/project.pbxproj +4 -0
  15. package/libusb/configure.ac +12 -2
  16. package/libusb/examples/hotplugtest.c +19 -11
  17. package/libusb/examples/listdevs.c +41 -3
  18. package/libusb/examples/xusb.c +6 -1
  19. package/libusb/libusb/Makefile.am +4 -0
  20. package/libusb/libusb/core.c +175 -14
  21. package/libusb/libusb/descriptor.c +163 -14
  22. package/libusb/libusb/io.c +7 -3
  23. package/libusb/libusb/libusb-1.0.def +10 -0
  24. package/libusb/libusb/libusb.h +59 -9
  25. package/libusb/libusb/libusbi.h +89 -25
  26. package/libusb/libusb/os/darwin_usb.c +126 -46
  27. package/libusb/libusb/os/darwin_usb.h +10 -8
  28. package/libusb/libusb/os/emscripten_webusb.cpp +31 -10
  29. package/libusb/libusb/os/haiku_usb_raw.cpp +4 -0
  30. package/libusb/libusb/os/linux_usbfs.c +73 -25
  31. package/libusb/libusb/os/netbsd_usb.c +2 -0
  32. package/libusb/libusb/os/openbsd_usb.c +2 -0
  33. package/libusb/libusb/os/sunos_usb.c +2 -0
  34. package/libusb/libusb/os/threads_posix.c +3 -3
  35. package/libusb/libusb/os/threads_posix.h +8 -2
  36. package/libusb/libusb/os/threads_windows.h +2 -1
  37. package/libusb/libusb/os/windows_common.c +86 -1
  38. package/libusb/libusb/os/windows_common.h +20 -1
  39. package/libusb/libusb/os/windows_hotplug.c +321 -0
  40. package/libusb/libusb/os/windows_hotplug.h +28 -0
  41. package/libusb/libusb/os/windows_usbdk.c +16 -8
  42. package/libusb/libusb/os/windows_winusb.c +753 -41
  43. package/libusb/libusb/os/windows_winusb.h +11 -6
  44. package/libusb/libusb/version.h +1 -1
  45. package/libusb/libusb/version_nano.h +1 -1
  46. package/libusb/msvc/Base.props +1 -1
  47. package/libusb/msvc/Configuration.Base.props +2 -1
  48. package/libusb/msvc/Configuration.DynamicLibrary.props +12 -0
  49. package/libusb/msvc/ProjectConfigurations.Base.props +69 -16
  50. package/libusb/msvc/build_all.ps1 +2 -2
  51. package/libusb/msvc/config.h +4 -0
  52. package/libusb/msvc/getopt/bits/getopt_core.h +96 -0
  53. package/libusb/msvc/getopt/bits/getopt_ext.h +77 -0
  54. package/libusb/msvc/getopt/features.h +21 -0
  55. package/libusb/msvc/getopt/getopt.c +456 -705
  56. package/libusb/msvc/getopt/getopt.h +16 -158
  57. package/libusb/msvc/getopt/getopt1.c +40 -69
  58. package/libusb/msvc/getopt/getopt_int.h +118 -0
  59. package/libusb/msvc/getopt/gettext.h +7 -0
  60. package/libusb/msvc/getopt/unistd.h +5 -0
  61. package/libusb/msvc/getopt.vcxproj +11 -4
  62. package/libusb/msvc/libusb.sln +515 -268
  63. package/libusb/msvc/libusb_dll.vcxproj +2 -0
  64. package/libusb/msvc/libusb_static.vcxproj +2 -0
  65. package/libusb/msvc/xusb.vcxproj +1 -1
  66. package/libusb/tests/Makefile.am +10 -1
  67. package/libusb/tests/fuzz/corpus/bos/min.bos +0 -0
  68. package/libusb/tests/fuzz/corpus/descriptor_parsers/min_valid_config.bin +0 -0
  69. package/libusb/tests/fuzz/corpus/descriptor_parsers/regression_bug_a_endpoint_null.bin +0 -0
  70. package/libusb/tests/fuzz/corpus/descriptor_parsers/regression_bug_b_iad_oob.bin +0 -0
  71. package/libusb/tests/fuzz/fuzz_bos_descriptor.c +49 -0
  72. package/libusb/tests/fuzz/fuzz_descriptor_parsers.c +83 -0
  73. package/libusb/tests/stress_mt.c +2 -1
  74. package/libusb/tests/webusb-test-shim/index.js +6 -5
  75. package/libusb.gypi +5 -0
  76. package/package.json +1 -1
  77. package/prebuilds/android-arm/node.napi.armv7.node +0 -0
  78. package/prebuilds/android-arm64/node.napi.armv8.node +0 -0
  79. package/prebuilds/darwin-x64+arm64/node.napi.node +0 -0
  80. package/prebuilds/linux-arm/node.napi.armv6.node +0 -0
  81. package/prebuilds/linux-arm/node.napi.armv7.node +0 -0
  82. package/prebuilds/linux-arm64/node.napi.armv8.node +0 -0
  83. package/prebuilds/linux-ia32/node.napi.node +0 -0
  84. package/prebuilds/linux-x64/node.napi.glibc.node +0 -0
  85. package/prebuilds/linux-x64/node.napi.musl.node +0 -0
  86. package/prebuilds/win32-arm64/node.napi.node +0 -0
  87. package/prebuilds/win32-ia32/node.napi.node +0 -0
  88. package/prebuilds/win32-x64/node.napi.node +0 -0
  89. package/src/{hotplug/libusb.cc → hotplug.cc} +2 -3
  90. package/src/{hotplug/hotplug.h → hotplug.h} +2 -6
  91. package/src/node_usb.cc +3 -3
  92. package/test/usb.coffee +4 -4
  93. package/test/webusb.coffee +22 -12
  94. package/src/hotplug/windows.cc +0 -168
@@ -382,6 +382,8 @@ if (cfg != desired)
382
382
  * - libusb_detach_kernel_driver()
383
383
  * - libusb_dev_mem_alloc()
384
384
  * - libusb_dev_mem_free()
385
+ * - libusb_endpoint_set_raw_io()
386
+ * - libusb_endpoint_supports_raw_io()
385
387
  * - libusb_error_name()
386
388
  * - libusb_event_handler_active()
387
389
  * - libusb_event_handling_ok()
@@ -404,6 +406,7 @@ if (cfg != desired)
404
406
  * - libusb_free_usb_2_0_extension_descriptor()
405
407
  * - libusb_get_active_config_descriptor()
406
408
  * - libusb_get_bos_descriptor()
409
+ * - libusb_get_session_data()
407
410
  * - libusb_get_bus_number()
408
411
  * - libusb_get_config_descriptor()
409
412
  * - libusb_get_config_descriptor_by_value()
@@ -415,10 +418,12 @@ if (cfg != desired)
415
418
  * - libusb_get_device_descriptor()
416
419
  * - libusb_get_device_list()
417
420
  * - libusb_get_device_speed()
421
+ * - libusb_get_device_string()
418
422
  * - libusb_get_iso_packet_buffer()
419
423
  * - libusb_get_iso_packet_buffer_simple()
420
424
  * - libusb_get_max_alt_packet_size()
421
425
  * - libusb_get_max_iso_packet_size()
426
+ * - libusb_get_max_raw_io_transfer_size()
422
427
  * - libusb_get_max_packet_size()
423
428
  * - libusb_get_next_timeout()
424
429
  * - libusb_get_parent()
@@ -499,6 +504,7 @@ if (cfg != desired)
499
504
  * - \ref libusb_capability
500
505
  * - \ref libusb_class_code
501
506
  * - \ref libusb_descriptor_type
507
+ * - \ref libusb_device_string_type
502
508
  * - \ref libusb_endpoint_direction
503
509
  * - \ref libusb_endpoint_transfer_type
504
510
  * - \ref libusb_error
@@ -722,26 +728,33 @@ struct libusb_device *usbi_alloc_device(struct libusb_context *ctx,
722
728
  dev->session_data = session_id;
723
729
  dev->speed = LIBUSB_SPEED_UNKNOWN;
724
730
 
725
- if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG))
726
- usbi_connect_device(dev);
731
+ /* Note: the device is NOT added to ctx->usb_devs here. The caller
732
+ * (backend) must call usbi_connect_device() after fully initializing
733
+ * the device's private data. This prevents a concurrent
734
+ * usbi_get_device_by_session_id() from finding a half-initialized
735
+ * device. */
727
736
 
728
737
  return dev;
729
738
  }
730
739
 
731
- void usbi_connect_device(struct libusb_device *dev)
740
+ void usbi_attach_device(struct libusb_device *dev)
732
741
  {
733
742
  struct libusb_context *ctx = DEVICE_CTX(dev);
734
743
 
735
744
  usbi_atomic_store(&dev->attached, 1);
736
745
 
737
- usbi_mutex_lock(&dev->ctx->usb_devs_lock);
738
- list_add(&dev->list, &dev->ctx->usb_devs);
739
- usbi_mutex_unlock(&dev->ctx->usb_devs_lock);
746
+ usbi_mutex_lock(&ctx->usb_devs_lock);
747
+ list_add(&dev->list, &ctx->usb_devs);
748
+ usbi_mutex_unlock(&ctx->usb_devs_lock);
749
+ }
740
750
 
741
- usbi_hotplug_notification(ctx, dev, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED);
751
+ void usbi_connect_device(struct libusb_device *dev)
752
+ {
753
+ usbi_attach_device(dev);
754
+ usbi_hotplug_notification(DEVICE_CTX(dev), dev, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED);
742
755
  }
743
756
 
744
- void usbi_disconnect_device(struct libusb_device *dev)
757
+ void usbi_detach_device(struct libusb_device *dev)
745
758
  {
746
759
  struct libusb_context *ctx = DEVICE_CTX(dev);
747
760
 
@@ -750,8 +763,12 @@ void usbi_disconnect_device(struct libusb_device *dev)
750
763
  usbi_mutex_lock(&ctx->usb_devs_lock);
751
764
  list_del(&dev->list);
752
765
  usbi_mutex_unlock(&ctx->usb_devs_lock);
766
+ }
753
767
 
754
- usbi_hotplug_notification(ctx, dev, LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT);
768
+ void usbi_disconnect_device(struct libusb_device *dev)
769
+ {
770
+ usbi_detach_device(dev);
771
+ usbi_hotplug_notification(DEVICE_CTX(dev), dev, LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT);
755
772
  }
756
773
 
757
774
  /* Perform some final sanity checks on a newly discovered device. If this
@@ -905,6 +922,26 @@ void API_EXPORTED libusb_free_device_list(libusb_device **list,
905
922
  free(list);
906
923
  }
907
924
 
925
+ /** \ingroup libusb_dev
926
+ * Returns the backend-specific identifier of the underlying system device tree
927
+ * node. Can be used to find the corresponding system device and directly query
928
+ * it (or access it otherwise) when and if necessary.
929
+ *
930
+ * Relevant backends:
931
+ * - Darwin: IOKit `sessionID`
932
+ * - Windows WinUSB: `DEVINST`
933
+ * - Linux, BSD: `busnum << 8 | devnum`
934
+ *
935
+ * Since version 1.0.30, \ref LIBUSB_API_VERSION >= 0x0100010C
936
+ *
937
+ * \param dev a device (must not be null)
938
+ * \returns the backend-specific device identifier
939
+ */
940
+ unsigned long API_EXPORTED libusb_get_session_data(libusb_device *dev)
941
+ {
942
+ return dev->session_data;
943
+ }
944
+
908
945
  /** \ingroup libusb_dev
909
946
  * Get the number of the bus that a device is connected to.
910
947
  * \param dev a device
@@ -1276,6 +1313,7 @@ libusb_device * LIBUSB_CALL libusb_ref_device(libusb_device *dev)
1276
1313
 
1277
1314
  refcnt = usbi_atomic_inc(&dev->refcnt);
1278
1315
  assert(refcnt >= 2);
1316
+ UNUSED(refcnt);
1279
1317
 
1280
1318
  return dev;
1281
1319
  }
@@ -1292,8 +1330,27 @@ void API_EXPORTED libusb_unref_device(libusb_device *dev)
1292
1330
  if (!dev)
1293
1331
  return;
1294
1332
 
1295
- refcnt = usbi_atomic_dec(&dev->refcnt);
1296
- assert(refcnt >= 0);
1333
+ if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
1334
+ /* Non-hotplug path: the decrement and conditional list removal
1335
+ * must be atomic with respect to usbi_get_device_by_session_id(),
1336
+ * which searches the list and refs the device under the same lock.
1337
+ * Without this, a concurrent search could find a device whose
1338
+ * refcnt has already reached zero and hit the assert in
1339
+ * libusb_ref_device(). */
1340
+ struct libusb_context *ctx = DEVICE_CTX(dev);
1341
+
1342
+ usbi_mutex_lock(&ctx->usb_devs_lock);
1343
+ refcnt = usbi_atomic_dec(&dev->refcnt);
1344
+ assert(refcnt >= 0);
1345
+ if (refcnt == 0 && usbi_atomic_load(&dev->attached)) {
1346
+ list_del(&dev->list);
1347
+ usbi_atomic_store(&dev->attached, 0);
1348
+ }
1349
+ usbi_mutex_unlock(&ctx->usb_devs_lock);
1350
+ } else {
1351
+ refcnt = usbi_atomic_dec(&dev->refcnt);
1352
+ assert(refcnt >= 0);
1353
+ }
1297
1354
 
1298
1355
  if (refcnt == 0) {
1299
1356
  usbi_dbg(DEVICE_CTX(dev), "destroy device %d.%d", dev->bus_number, dev->device_address);
@@ -1303,9 +1360,8 @@ void API_EXPORTED libusb_unref_device(libusb_device *dev)
1303
1360
  if (usbi_backend.destroy_device)
1304
1361
  usbi_backend.destroy_device(dev);
1305
1362
 
1306
- if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
1307
- /* backend does not support hotplug */
1308
- usbi_disconnect_device(dev);
1363
+ for (int idx = 0; idx < LIBUSB_DEVICE_STRING_COUNT; ++idx) {
1364
+ free(dev->device_strings_utf8[idx]);
1309
1365
  }
1310
1366
 
1311
1367
  free(dev);
@@ -2204,6 +2260,111 @@ int API_EXPORTED libusb_set_auto_detach_kernel_driver(
2204
2260
  return LIBUSB_SUCCESS;
2205
2261
  }
2206
2262
 
2263
+ /** \ingroup libusb_dev
2264
+ * Check if the endpoint supports RAW_IO.
2265
+ * \param dev_handle a device handle
2266
+ * \param endpoint the endpoint to check
2267
+ *
2268
+ * \returns 1 if the endpoint supports RAW_IO
2269
+ * \returns 0 if the endpoint does not support RAW_IO
2270
+ * \returns a LIBUSB_ERROR code on failure
2271
+ *
2272
+ * Only endpoints using the WinUSB driver support RAW_IO,
2273
+ * for all other backends/drivers this function will return 0.
2274
+ *
2275
+ * Fails if the interface the endpoint belongs to isn't claimed,
2276
+ * \see libusb_claim_interface().
2277
+ *
2278
+ * \see libusb_endpoint_set_raw_io()
2279
+ *
2280
+ * Since version 1.0.30, \ref LIBUSB_API_VERSION >= 0x0100010C
2281
+ */
2282
+ int API_EXPORTED libusb_endpoint_supports_raw_io(libusb_device_handle* dev_handle,
2283
+ uint8_t endpoint)
2284
+ {
2285
+ if (usbi_backend.endpoint_supports_raw_io == NULL)
2286
+ {
2287
+ return 0;
2288
+ }
2289
+
2290
+ // If the `endpoint_supports_raw_io` function is present, these two should be too:
2291
+ assert(usbi_backend.endpoint_set_raw_io != NULL);
2292
+ assert(usbi_backend.get_max_raw_io_transfer_size != NULL);
2293
+
2294
+ return usbi_backend.endpoint_supports_raw_io(dev_handle, endpoint);
2295
+ }
2296
+
2297
+ /** \ingroup libusb_dev
2298
+ * Enable/disable RAW_IO for an endpoint on an open device.
2299
+ *
2300
+ * Only endpoints using the WinUSB driver support RAW_IO,
2301
+ * for all other backends/drivers this function will return an error code.
2302
+ *
2303
+ * Using RAW_IO can greatly improve USB throughput by directly passing
2304
+ * transfer requests to the underlying USB driver instead of queuing them
2305
+ * in WinUSB. This can be particularly useful for high-throughput devices
2306
+ * like cameras or oscilloscopes.
2307
+ *
2308
+ * Transfers submitted to the endpoint while RAW_IO is enabled will fail unless
2309
+ * they adhere to the following rules :
2310
+ * - The buffer length must be a multiple of the maximum endpoint packet size
2311
+ * \see libusb_get_max_packet_size.
2312
+ * - The buffer length must be less than or equal to the value returned by
2313
+ * \ref libusb_get_max_raw_io_transfer_size.
2314
+ *
2315
+ * This option should not be changed when any transfer is in progress on
2316
+ * the specified endpoint.
2317
+ *
2318
+ * Fails if the interface the endpoint belongs to isn't claimed,
2319
+ * \see libusb_claim_interface().
2320
+ *
2321
+ * \param dev_handle a device handle
2322
+ * \param endpoint the endpoint to set RAW_IO for
2323
+ * \param enable 1 to enable RAW_IO, 0 to disable it
2324
+ *
2325
+ * \returns \ref LIBUSB_SUCCESS on success
2326
+ * \returns \ref LIBUSB_ERROR_NOT_SUPPORTED if the backend does not support RAW_IO.
2327
+ * \returns another LIBUSB_ERROR code on other failure
2328
+ *
2329
+ * \see libusb_endpoint_supports_raw_io()
2330
+ * \see https://learn.microsoft.com/en-us/windows-hardware/drivers/usbcon/winusb-functions-for-pipe-policy-modification
2331
+ *
2332
+ * Since version 1.0.30, \ref LIBUSB_API_VERSION >= 0x0100010C
2333
+ */
2334
+ int API_EXPORTED libusb_endpoint_set_raw_io(libusb_device_handle* dev_handle,
2335
+ uint8_t endpoint, int enable)
2336
+ {
2337
+ if (!usbi_backend.endpoint_set_raw_io)
2338
+ return LIBUSB_ERROR_NOT_SUPPORTED;
2339
+
2340
+ return usbi_backend.endpoint_set_raw_io(dev_handle, endpoint, enable);
2341
+ }
2342
+
2343
+ /** \ingroup libusb_dev
2344
+ * Retrieve the maximum transfer size in bytes supported for WinUSB RAW_IO
2345
+ * for an inbound bulk or interrupt endpoint on an open device.
2346
+ *
2347
+ * Returns a maximum transfer size in bytes, or a negative error code.
2348
+ * If the backend does not support WinUSB RAW_IO, returns
2349
+ * \ref LIBUSB_ERROR_NOT_SUPPORTED.
2350
+ *
2351
+ * Fails if the interface the endpoint belongs to isn't claimed,
2352
+ * \see libusb_claim_interface().
2353
+ *
2354
+ * \see libusb_endpoint_set_raw_io()
2355
+ *
2356
+ * Since version 1.0.30, \ref LIBUSB_API_VERSION >= 0x0100010C
2357
+ */
2358
+ int API_EXPORTED libusb_get_max_raw_io_transfer_size(
2359
+ libusb_device_handle *dev_handle, uint8_t endpoint)
2360
+ {
2361
+ if (!usbi_backend.get_max_raw_io_transfer_size)
2362
+ return LIBUSB_ERROR_NOT_SUPPORTED;
2363
+
2364
+ return usbi_backend.get_max_raw_io_transfer_size(
2365
+ dev_handle, endpoint);
2366
+ }
2367
+
2207
2368
  /** \ingroup libusb_lib
2208
2369
  * Deprecated. Use libusb_set_option() or libusb_init_context() instead,
2209
2370
  * with the \ref LIBUSB_OPTION_LOG_LEVEL option.
@@ -38,10 +38,10 @@ static inline uint16_t ReadLittleEndian16(const uint8_t p[2])
38
38
 
39
39
  static inline uint32_t ReadLittleEndian32(const uint8_t p[4])
40
40
  {
41
- return (uint32_t)((uint32_t)p[3] << 24 |
42
- (uint32_t)p[2] << 16 |
43
- (uint32_t)p[1] << 8 |
44
- (uint32_t)p[0]);
41
+ return ((uint32_t)p[3] << 24 |
42
+ (uint32_t)p[2] << 16 |
43
+ (uint32_t)p[1] << 8 |
44
+ (uint32_t)p[0]);
45
45
  }
46
46
 
47
47
  static void clear_endpoint(struct libusb_endpoint_descriptor *endpoint)
@@ -148,6 +148,8 @@ static void clear_interface(struct libusb_interface *usb_interface)
148
148
  usb_interface->altsetting + i;
149
149
 
150
150
  free((void *)ifp->extra);
151
+ ifp->extra = NULL;
152
+ ifp->extra_length = 0;
151
153
  if (ifp->endpoint) {
152
154
  uint8_t j;
153
155
 
@@ -156,10 +158,13 @@ static void clear_interface(struct libusb_interface *usb_interface)
156
158
  ifp->endpoint + j);
157
159
  }
158
160
  free((void *)ifp->endpoint);
161
+ ifp->endpoint = NULL;
162
+ ifp->bNumEndpoints = 0;
159
163
  }
160
164
  }
161
165
  free((void *)usb_interface->altsetting);
162
166
  usb_interface->altsetting = NULL;
167
+ usb_interface->num_altsetting = 0;
163
168
  }
164
169
 
165
170
  static int parse_interface(libusb_context *ctx,
@@ -241,6 +246,10 @@ static int parse_interface(libusb_context *ctx,
241
246
  usbi_warn(ctx,
242
247
  "short extra intf desc read %d/%u",
243
248
  size, header->bLength);
249
+ /* Keep the invariant: bNumEndpoints > 0 implies
250
+ * endpoint != NULL. The endpoint array isn't
251
+ * allocated yet on this early return. */
252
+ ifp->bNumEndpoints = 0;
244
253
  return parsed;
245
254
  }
246
255
 
@@ -322,7 +331,11 @@ static void clear_configuration(struct libusb_config_descriptor *config)
322
331
  config->interface + i);
323
332
  }
324
333
  free((void *)config->interface);
334
+ config->interface = NULL;
335
+ config->bNumInterfaces = 0;
325
336
  free((void *)config->extra);
337
+ config->extra = NULL;
338
+ config->extra_length = 0;
326
339
  }
327
340
 
328
341
  static int parse_configuration(struct libusb_context *ctx,
@@ -423,7 +436,7 @@ static int parse_configuration(struct libusb_context *ctx,
423
436
  config->extra_length += (int)len;
424
437
  }
425
438
 
426
- r = parse_interface(ctx, usb_interface + i, buffer, (int)size);
439
+ r = parse_interface(ctx, usb_interface + i, buffer, size);
427
440
  if (r < 0)
428
441
  goto err;
429
442
  if (r == 0) {
@@ -777,7 +790,7 @@ static int parse_bos(struct libusb_context *ctx,
777
790
  return LIBUSB_ERROR_IO;
778
791
  }
779
792
 
780
- _bos = calloc(1, sizeof(*_bos) + bos_desc->bNumDeviceCaps * sizeof(void *));
793
+ _bos = calloc(1, sizeof(*_bos) + (bos_desc->bNumDeviceCaps * sizeof(void *)));
781
794
  if (!_bos)
782
795
  return LIBUSB_ERROR_NO_MEM;
783
796
 
@@ -1082,7 +1095,7 @@ int API_EXPORTED libusb_get_ssplus_usb_device_capability_descriptor(
1082
1095
  parsedDescriptor.wReserved = ReadLittleEndian16(&dev_capability_data[7]);
1083
1096
 
1084
1097
  uint8_t numSublikSpeedAttributes = (parsedDescriptor.bmAttributes & 0xF) + 1;
1085
- _ssplus_cap = malloc(sizeof(struct libusb_ssplus_usb_device_capability_descriptor) + numSublikSpeedAttributes * sizeof(struct libusb_ssplus_sublink_attribute));
1098
+ _ssplus_cap = malloc(sizeof(struct libusb_ssplus_usb_device_capability_descriptor) + (numSublikSpeedAttributes * sizeof(struct libusb_ssplus_sublink_attribute)));
1086
1099
  if (!_ssplus_cap)
1087
1100
  return LIBUSB_ERROR_NO_MEM;
1088
1101
 
@@ -1096,7 +1109,8 @@ int API_EXPORTED libusb_get_ssplus_usb_device_capability_descriptor(
1096
1109
  _ssplus_cap->minTxLaneCount = (parsedDescriptor.wFunctionalitySupport & 0xF000) >> 12;
1097
1110
 
1098
1111
  /* Check that we have enough to read all the sublink attributes */
1099
- if (dev_cap->bLength < LIBUSB_BT_SSPLUS_USB_DEVICE_CAPABILITY_SIZE + _ssplus_cap->numSublinkSpeedAttributes * sizeof(uint32_t)) {
1112
+ if (dev_cap->bLength < LIBUSB_BT_SSPLUS_USB_DEVICE_CAPABILITY_SIZE + (_ssplus_cap->numSublinkSpeedAttributes * sizeof(uint32_t))) {
1113
+ free(_ssplus_cap);
1100
1114
  usbi_err(ctx, "short ssplus capability descriptor, unable to read sublinks: Not enough data");
1101
1115
  return LIBUSB_ERROR_IO;
1102
1116
  }
@@ -1104,7 +1118,7 @@ int API_EXPORTED libusb_get_ssplus_usb_device_capability_descriptor(
1104
1118
  /* Read the attributes */
1105
1119
  uint8_t* base = ((uint8_t*)dev_cap) + LIBUSB_BT_SSPLUS_USB_DEVICE_CAPABILITY_SIZE;
1106
1120
  for(uint8_t i = 0 ; i < _ssplus_cap->numSublinkSpeedAttributes ; i++) {
1107
- uint32_t attr = ReadLittleEndian32(base + i * sizeof(uint32_t));
1121
+ uint32_t attr = ReadLittleEndian32(base + (i * sizeof(uint32_t)));
1108
1122
  _ssplus_cap->sublinkSpeedAttributes[i].ssid = attr & 0x0f;
1109
1123
  _ssplus_cap->sublinkSpeedAttributes[i].mantissa = attr >> 16;
1110
1124
  _ssplus_cap->sublinkSpeedAttributes[i].exponent = (attr >> 4) & 0x3 ;
@@ -1311,9 +1325,10 @@ int API_EXPORTED libusb_get_string_descriptor_ascii(libusb_device_handle *dev_ha
1311
1325
  r = libusb_get_string_descriptor(dev_handle, 0, 0, str.buf, 4);
1312
1326
  if (r < 0)
1313
1327
  return r;
1314
- else if (r != 4 || str.desc.bLength < 4 || str.desc.bDescriptorType != LIBUSB_DT_STRING)
1328
+ else if (r != 4 || str.desc.bLength < 4 || str.desc.bDescriptorType != LIBUSB_DT_STRING) {
1329
+ usbi_warn(HANDLE_CTX(dev_handle), "invalid language ID string descriptor");
1315
1330
  return LIBUSB_ERROR_IO;
1316
- else if (str.desc.bLength & 1)
1331
+ } else if (str.desc.bLength & 1)
1317
1332
  usbi_warn(HANDLE_CTX(dev_handle), "suspicious bLength %u for language ID string descriptor", str.desc.bLength);
1318
1333
 
1319
1334
  langid = libusb_le16_to_cpu(str.desc.wData[0]);
@@ -1365,7 +1380,7 @@ static int parse_iad_array(struct libusb_context *ctx,
1365
1380
 
1366
1381
  /* First pass: Iterate through desc list, count number of IADs */
1367
1382
  iad_array->length = 0;
1368
- while (consumed < size) {
1383
+ while (size - consumed >= DESC_HEADER_LENGTH) {
1369
1384
  header.bLength = buf[0];
1370
1385
  header.bDescriptorType = buf[1];
1371
1386
  if (header.bLength < DESC_HEADER_LENGTH) {
@@ -1373,9 +1388,9 @@ static int parse_iad_array(struct libusb_context *ctx,
1373
1388
  header.bLength);
1374
1389
  return LIBUSB_ERROR_IO;
1375
1390
  }
1376
- else if (header.bLength > size) {
1391
+ else if (header.bLength > size - consumed) {
1377
1392
  usbi_warn(ctx, "short config descriptor read %d/%u",
1378
- size, header.bLength);
1393
+ size - consumed, header.bLength);
1379
1394
  return LIBUSB_ERROR_IO;
1380
1395
  }
1381
1396
  if (header.bDescriptorType == LIBUSB_DT_INTERFACE_ASSOCIATION)
@@ -1556,3 +1571,137 @@ void API_EXPORTED libusb_free_interface_association_descriptors(
1556
1571
  free((void*)iad_array->iad);
1557
1572
  free(iad_array);
1558
1573
  }
1574
+
1575
+ /*
1576
+ * \brief Copy a UTF-8 string with proper truncation if needed.
1577
+ *
1578
+ * \param tgt The target utf-8 string. If NULL, then tgt is ignored,
1579
+ * tgt_size is forced to 0, and this function returns the
1580
+ * required tgt_size for a subsequent call to this function.
1581
+ * \param src The source utf-8 string. If NULL, then
1582
+ * the source string is empty, the return length is 1,
1583
+ * and, if tgt is not NULL, this function
1584
+ * sets tgt[0] to the null terminator.
1585
+ * \param tgt_size The size of target in bytes.
1586
+ * \return the length of src in bytes, including the null terminator.
1587
+ *
1588
+ * utf8_copy(NULL, src, 0) is equivalent to strlen(src) + 1.
1589
+ */
1590
+ static int usbi_utf8_copy(char *tgt, char const *src, int tgt_size) {
1591
+ uint8_t* t = (uint8_t*)tgt;
1592
+ uint8_t const* s = (uint8_t const*)src;
1593
+
1594
+ if (NULL == src) {
1595
+ if ((NULL != tgt) && (tgt_size > 0)) {
1596
+ tgt[0] = 0;
1597
+ }
1598
+ return 1;
1599
+ }
1600
+
1601
+ if ((NULL == tgt) || (tgt_size <= 0)) {
1602
+ return (int)(strlen(src) + 1);
1603
+ }
1604
+
1605
+ // copy UTF-8 string and compute length
1606
+ int k = 0;
1607
+ for (k = 0; s[k]; ++k) {
1608
+ if (k < tgt_size) {
1609
+ t[k] = s[k];
1610
+ } else {
1611
+ break;
1612
+ }
1613
+ }
1614
+
1615
+ if (k >= tgt_size) {
1616
+ // truncate respecting UTF-8 character boundaries
1617
+ int idx = tgt_size - 1;
1618
+ while (idx && (0x80 == (t[idx] & 0xC0))) { // utf-8 continuation byte
1619
+ --idx;
1620
+ }
1621
+ t[idx] = 0;
1622
+ return (int)(strlen(src) + 1);
1623
+ } else {
1624
+ t[k++] = 0;
1625
+ return k;
1626
+ }
1627
+ }
1628
+
1629
+ /** \ingroup libusb_desc
1630
+ * Retrieve a device string without needing to open the device.
1631
+ *
1632
+ * Since version v1.0.30 \ref LIBUSB_API_VERSION >= 0x0100010C
1633
+ *
1634
+ * \param dev the target device
1635
+ * \param string_type the string type to retrieve
1636
+ * \param data the data buffer for the UTF-8 encoded string.
1637
+ * \param length the size of the data buffer in bytes.
1638
+ * USB string descriptors cannot be longer than
1639
+ * LIBUSB_DEVICE_STRING_BYTES_MAX.
1640
+ * \returns a negative error code or
1641
+ * the actual string length in bytes including the null terminator.
1642
+ * \see libusb_get_string_descriptor()
1643
+ * \see libusb_get_string_descriptor_ascii()
1644
+ *
1645
+ * This function works when the device is still closed since it relies
1646
+ * on the operating system to provide the string. The operating system
1647
+ * normally reads and caches the common string descriptors during
1648
+ * USB enumeration.
1649
+ *
1650
+ * Since the USB string descriptor could be processed by the OS,
1651
+ * this function returns a UTF-8 encoded string.
1652
+ *
1653
+ * The string will be returned untranslated or in the default OS language
1654
+ * when supported by the OS and USB device.
1655
+ *
1656
+ * One way to call this function is using a buffer on the stack:
1657
+ *
1658
+ * char buffer[LIBUSB_DEVICE_STRING_BYTES_MAX];
1659
+ * int ret = libusb_get_device_string(dev, LIBUSB_DEVICE_STRING_SERIAL_NUMBER, buffer, sizeof(buffer));
1660
+ * if (ret < 0) {
1661
+ * // handle error
1662
+ * }
1663
+ *
1664
+ * This function is commonly used to get the serial number to allow
1665
+ * for device selection before opening the selected device.
1666
+ */
1667
+ int API_EXPORTED libusb_get_device_string(libusb_device *dev,
1668
+ enum libusb_device_string_type string_type, char *data, int length) {
1669
+ char * s;
1670
+ if (NULL == dev) {
1671
+ return LIBUSB_ERROR_INVALID_PARAM;
1672
+ }
1673
+ if ((string_type < 0) || (string_type >= LIBUSB_DEVICE_STRING_COUNT)) {
1674
+ return LIBUSB_ERROR_INVALID_PARAM;
1675
+ }
1676
+ if (length <= 0) {
1677
+ return LIBUSB_ERROR_INVALID_PARAM;
1678
+ }
1679
+ if (NULL == data) {
1680
+ length = 0;
1681
+ data = NULL;
1682
+ } else if (length > 0) {
1683
+ *data = 0; // return an empty string on errors when possible
1684
+ }
1685
+
1686
+ if (NULL == dev->device_strings_utf8[string_type]) {
1687
+ if (usbi_backend.get_device_string) {
1688
+ s = malloc(LIBUSB_DEVICE_STRING_BYTES_MAX);
1689
+ int rv = usbi_backend.get_device_string(dev, string_type, s, LIBUSB_DEVICE_STRING_BYTES_MAX);
1690
+ if (rv < 0) {
1691
+ free(s);
1692
+ return rv;
1693
+ } else {
1694
+ dev->device_strings_utf8[string_type] = s;
1695
+ }
1696
+ } else {
1697
+ return LIBUSB_ERROR_NOT_SUPPORTED;
1698
+ }
1699
+ }
1700
+
1701
+ s = dev->device_strings_utf8[string_type];
1702
+ if (NULL == s) {
1703
+ return LIBUSB_ERROR_NOT_SUPPORTED;
1704
+ }
1705
+
1706
+ return usbi_utf8_copy(data, s, length);
1707
+ }
@@ -1303,7 +1303,6 @@ struct libusb_transfer * LIBUSB_CALL libusb_alloc_transfer(
1303
1303
  return NULL;
1304
1304
 
1305
1305
  struct usbi_transfer *itransfer = (struct usbi_transfer *)(ptr + priv_size);
1306
- itransfer->num_iso_packets = iso_packets;
1307
1306
  itransfer->priv = ptr;
1308
1307
  usbi_mutex_init(&itransfer->lock);
1309
1308
  struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
@@ -1370,8 +1369,10 @@ static int arm_timer_for_next_timeout(struct libusb_context *ctx)
1370
1369
 
1371
1370
  /* act on first transfer that has not already been handled */
1372
1371
  if (!(itransfer->timeout_flags & (USBI_TRANSFER_TIMEOUT_HANDLED | USBI_TRANSFER_OS_HANDLES_TIMEOUT))) {
1372
+ #ifdef ENABLE_LOGGING
1373
1373
  struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1374
1374
  usbi_dbg(ctx, "next timeout originally %ums", transfer->timeout);
1375
+ #endif
1375
1376
  return usbi_arm_timer(&ctx->timer, cur_ts);
1376
1377
  }
1377
1378
  }
@@ -1434,9 +1435,11 @@ out:
1434
1435
  if (first && usbi_using_timer(ctx) && TIMESPEC_IS_SET(timeout)) {
1435
1436
  /* if this transfer has the lowest timeout of all active transfers,
1436
1437
  * rearm the timer with this transfer's timeout */
1438
+ #ifdef ENABLE_LOGGING
1437
1439
  struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1438
1440
  usbi_dbg(ctx, "arm timer for timeout in %ums (first in line)",
1439
1441
  transfer->timeout);
1442
+ #endif
1440
1443
  r = usbi_arm_timer(&ctx->timer, timeout);
1441
1444
  }
1442
1445
  #else
@@ -2811,9 +2814,8 @@ void API_EXPORTED libusb_free_pollfds(const struct libusb_pollfd **pollfds)
2811
2814
  * device. This function ensures transfers get cancelled appropriately.
2812
2815
  * Callers of this function must hold the events_lock.
2813
2816
  */
2814
- void usbi_handle_disconnect(struct libusb_device_handle *dev_handle)
2817
+ void usbi_handle_disconnect(struct libusb_context *ctx, struct libusb_device_handle *dev_handle)
2815
2818
  {
2816
- struct libusb_context *ctx = HANDLE_CTX(dev_handle);
2817
2819
  struct usbi_transfer *cur;
2818
2820
  struct usbi_transfer *to_cancel;
2819
2821
 
@@ -2853,9 +2855,11 @@ void usbi_handle_disconnect(struct libusb_device_handle *dev_handle)
2853
2855
  if (!to_cancel)
2854
2856
  break;
2855
2857
 
2858
+ #ifdef ENABLE_LOGGING
2856
2859
  struct libusb_transfer *transfer_to_cancel = USBI_TRANSFER_TO_LIBUSB_TRANSFER(to_cancel);
2857
2860
  usbi_dbg(ctx, "cancelling transfer %p from disconnect",
2858
2861
  (void *) transfer_to_cancel);
2862
+ #endif
2859
2863
 
2860
2864
  usbi_mutex_lock(&to_cancel->lock);
2861
2865
  usbi_backend.clear_transfer_priv(to_cancel);
@@ -24,6 +24,10 @@ EXPORTS
24
24
  libusb_dev_mem_alloc@8 = libusb_dev_mem_alloc
25
25
  libusb_dev_mem_free
26
26
  libusb_dev_mem_free@12 = libusb_dev_mem_free
27
+ libusb_endpoint_set_raw_io
28
+ libusb_endpoint_set_raw_io@12 = libusb_endpoint_set_raw_io
29
+ libusb_endpoint_supports_raw_io
30
+ libusb_endpoint_supports_raw_io@8 = libusb_endpoint_supports_raw_io
27
31
  libusb_error_name
28
32
  libusb_error_name@4 = libusb_error_name
29
33
  libusb_event_handler_active
@@ -84,6 +88,8 @@ EXPORTS
84
88
  libusb_get_device_list@8 = libusb_get_device_list
85
89
  libusb_get_device_speed
86
90
  libusb_get_device_speed@4 = libusb_get_device_speed
91
+ libusb_get_device_string
92
+ libusb_get_device_string@16 = libusb_get_device_string
87
93
  libusb_get_interface_association_descriptors
88
94
  libusb_get_interface_association_descriptors@12 = libusb_get_interface_association_descriptors
89
95
  libusb_get_max_alt_packet_size
@@ -92,6 +98,8 @@ EXPORTS
92
98
  libusb_get_max_iso_packet_size@8 = libusb_get_max_iso_packet_size
93
99
  libusb_get_max_packet_size
94
100
  libusb_get_max_packet_size@8 = libusb_get_max_packet_size
101
+ libusb_get_max_raw_io_transfer_size
102
+ libusb_get_max_raw_io_transfer_size@8 = libusb_get_max_raw_io_transfer_size
95
103
  libusb_get_next_timeout
96
104
  libusb_get_next_timeout@8 = libusb_get_next_timeout
97
105
  libusb_get_parent
@@ -106,6 +114,8 @@ EXPORTS
106
114
  libusb_get_port_numbers@12 = libusb_get_port_numbers
107
115
  libusb_get_port_path
108
116
  libusb_get_port_path@16 = libusb_get_port_path
117
+ libusb_get_session_data
118
+ libusb_get_session_data@4 = libusb_get_session_data
109
119
  libusb_get_ss_endpoint_companion_descriptor
110
120
  libusb_get_ss_endpoint_companion_descriptor@12 = libusb_get_ss_endpoint_companion_descriptor
111
121
  libusb_get_ss_usb_device_capability_descriptor