From ec0722fc0d552b8e6f8317f7041b4e6441d087f2 Mon Sep 17 00:00:00 2001 From: Kevin Mehall Date: Sun, 10 Dec 2023 13:37:06 -0800 Subject: [PATCH] macos: Support getting configuration descriptors --- src/platform/macos_iokit/device.rs | 3 ++- src/platform/macos_iokit/iokit_usb.rs | 28 +++++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/platform/macos_iokit/device.rs b/src/platform/macos_iokit/device.rs index c378994..df5f12b 100644 --- a/src/platform/macos_iokit/device.rs +++ b/src/platform/macos_iokit/device.rs @@ -34,7 +34,8 @@ impl MacDevice { } pub(crate) fn configuration_descriptors(&self) -> impl Iterator { - [].into_iter() + let num_configs = self.device.get_number_of_configurations().unwrap_or(0); + (0..num_configs).flat_map(|i| self.device.get_configuration_descriptor(i).ok()) } pub(crate) fn set_configuration(&self, configuration: u8) -> Result<(), Error> { diff --git a/src/platform/macos_iokit/iokit_usb.rs b/src/platform/macos_iokit/iokit_usb.rs index 6cc76cd..63bb5b1 100644 --- a/src/platform/macos_iokit/iokit_usb.rs +++ b/src/platform/macos_iokit/iokit_usb.rs @@ -3,7 +3,7 @@ //! Based on Kate Temkin's [usrs](https://github.com/ktemkin/usrs) //! licensed under MIT OR Apache-2.0. -use std::{collections::BTreeMap, io::ErrorKind, time::Duration}; +use std::{collections::BTreeMap, io::ErrorKind, ptr, slice, time::Duration}; use core_foundation::{base::TCFType, runloop::CFRunLoopSource}; use core_foundation_sys::runloop::CFRunLoopSourceRef; @@ -27,7 +27,8 @@ use super::{ }, iokit_c::{ kIOCFPlugInInterfaceID, kIOUSBFindInterfaceDontCare, kIOUsbDeviceUserClientTypeID, - IOCFPlugInInterface, IOCreatePlugInInterfaceForService, IOUSBFindInterfaceRequest, + IOCFPlugInInterface, IOCreatePlugInInterfaceForService, IOUSBConfigurationDescriptor, + IOUSBFindInterfaceRequest, }, }; @@ -146,6 +147,29 @@ impl IoKitDevice { Ok(IoServiceIterator::new(iterator)) } } + + pub(crate) fn get_number_of_configurations(&self) -> Result { + unsafe { + let mut num = 0; + check_iokit_return(call_iokit_function!( + self.raw, + GetNumberOfConfigurations(&mut num) + ))?; + Ok(num) + } + } + + pub(crate) fn get_configuration_descriptor(&self, index: u8) -> Result<&[u8], Error> { + unsafe { + let mut ptr: *mut IOUSBConfigurationDescriptor = ptr::null_mut(); + check_iokit_return(call_iokit_function!( + self.raw, + GetConfigurationDescriptorPtr(index, &mut ptr) + ))?; + let len = u16::to_le((*ptr).wTotalLength) as usize; + Ok(slice::from_raw_parts(ptr as *const u8, len)) + } + } } impl Drop for IoKitDevice {