Merge pull request #148 from kevinmehall/macos-update

macOS: Update core-foundation, switch to IOUSBInterfaceInterface700 and IOUSBDeviceInterface650
This commit is contained in:
Kevin Mehall 2025-06-15 14:35:17 -06:00 committed by GitHub
commit 915f79005d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 210 additions and 63 deletions

View file

@ -28,7 +28,7 @@ linux-raw-sys = { version = "0.9.2", features = ["ioctl"] }
windows-sys = { version = "0.59.0", features = ["Win32_Devices_Usb", "Win32_Devices_DeviceAndDriverInstallation", "Win32_Foundation", "Win32_Devices_Properties", "Win32_Storage_FileSystem", "Win32_Security", "Win32_System_IO", "Win32_System_Registry", "Win32_System_Com"] }
[target.'cfg(target_os="macos")'.dependencies]
core-foundation = "0.9.3"
core-foundation = "0.10.1"
core-foundation-sys = "0.8.4"
io-kit-sys = "0.4.0"

View file

@ -1,5 +1,4 @@
use std::{
ops::Deref,
sync::{mpsc, Mutex},
thread,
};
@ -8,23 +7,13 @@ use core_foundation::runloop::{CFRunLoop, CFRunLoopSource};
use core_foundation_sys::runloop::kCFRunLoopCommonModes;
use log::info;
// Pending release of https://github.com/servo/core-foundation-rs/pull/610
struct SendCFRunLoop(CFRunLoop);
unsafe impl Send for SendCFRunLoop {}
impl Deref for SendCFRunLoop {
type Target = CFRunLoop;
fn deref(&self) -> &Self::Target {
&self.0
}
}
// Pending https://github.com/servo/core-foundation-rs/pull/649
struct SendCFRunLoopSource(CFRunLoopSource);
unsafe impl Send for SendCFRunLoopSource {}
unsafe impl Sync for SendCFRunLoopSource {}
struct EventLoop {
runloop: Option<SendCFRunLoop>,
runloop: Option<CFRunLoop>,
count: usize,
}
@ -49,7 +38,7 @@ pub(crate) fn add_event_source(source: CFRunLoopSource) -> EventRegistration {
let runloop = CFRunLoop::get_current();
let source = source;
runloop.add_source(&source.0, unsafe { kCFRunLoopCommonModes });
tx.send(SendCFRunLoop(runloop)).unwrap();
tx.send(runloop).unwrap();
CFRunLoop::run_current();
info!("event loop thread exited");
});

View file

@ -99,19 +99,17 @@ impl Drop for PluginInterface {
}
}
/// Alias that select the "version 500" (IOKit 5.0.0) version of UsbDevice, which means
/// that we support macOS versions back to 10.7.3, which is currently every version that Rust
/// supports. Use this instead of touching the iokit_c structure; this may be bumped to
/// (compatible) newer versions of the struct as Rust's support changes.
pub(crate) type UsbDevice = iokit_c::IOUSBDeviceStruct500;
pub(crate) type UsbInterface = iokit_c::IOUSBInterfaceStruct500;
/// Alias to select the "version 650" version of UsbDevice, and and "version 700" of UsbInterface.
/// These are supported on macOS versions back to 10.10, which is older than Rust's minimum supported version of 10.12.
pub(crate) type UsbDevice = iokit_c::IOUSBDeviceStruct650;
pub(crate) type UsbInterface = iokit_c::IOUSBInterfaceStruct700;
pub(crate) fn usb_device_type_id() -> CFUUIDBytes {
unsafe { CFUUIDGetUUIDBytes(iokit_c::kIOUSBDeviceInterfaceID500()) }
unsafe { CFUUIDGetUUIDBytes(iokit_c::kIOUSBDeviceInterfaceID650()) }
}
pub(crate) fn usb_interface_type_id() -> CFUUIDBytes {
unsafe { CFUUIDGetUUIDBytes(iokit_c::kIOUSBInterfaceInterfaceID500()) }
unsafe { CFUUIDGetUUIDBytes(iokit_c::kIOUSBInterfaceInterfaceID700()) }
}
pub(crate) fn check_iokit_return(r: IOReturn) -> Result<(), IOReturn> {

View file

@ -22,7 +22,7 @@ use core_foundation_sys::{
use io_kit_sys::{
ret::IOReturn,
types::{io_iterator_t, io_service_t, IOByteCount},
IOAsyncCallback1,
IOAsyncCallback1, IOAsyncCallback2,
};
//
@ -77,6 +77,24 @@ pub(crate) type USBDeviceAddress = UInt16;
pub(crate) type AbsoluteTime = UnsignedWide;
pub(crate) type Boolean = std::os::raw::c_uchar;
#[repr(C, packed)]
#[derive(Debug, Copy, Clone)]
pub struct IOUSBEndpointProperties {
pub bVersion: UInt8,
pub bAlternateSetting: UInt8,
pub bDirection: UInt8,
pub bEndpointNumber: UInt8,
pub bTransferType: UInt8,
pub bUsageType: UInt8,
pub bSyncType: UInt8,
pub bInterval: UInt8,
pub wMaxPacketSize: UInt16,
pub bMaxBurst: UInt8,
pub bMaxStreams: UInt8,
pub bMult: UInt8,
pub wBytesPerInterval: UInt16,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct NumVersion {
@ -297,50 +315,50 @@ pub fn kIOCFPlugInInterfaceID() -> CFUUIDRef {
}
}
pub fn kIOUSBDeviceInterfaceID500() -> CFUUIDRef {
pub fn kIOUSBDeviceInterfaceID650() -> CFUUIDRef {
unsafe {
CFUUIDGetConstantUUIDWithBytes(
kCFAllocatorSystemDefault,
0xA3,
0x3C,
0xF0,
0x4A,
0xAC,
0x1B,
0x2E,
0x24,
0xC2,
0x47,
0x4B,
0x5B,
0x48,
0xE2,
0xB5,
0x7D,
0x02,
0x07,
0xFC,
0xEA,
0xE1,
0x3B,
0x6A,
0x96,
0x4D,
0x91,
0x33,
0x35,
0x34,
0xF2,
0xCC,
)
}
}
pub fn kIOUSBInterfaceInterfaceID500() -> CFUUIDRef {
pub fn kIOUSBInterfaceInterfaceID700() -> CFUUIDRef {
unsafe {
CFUUIDGetConstantUUIDWithBytes(
kCFAllocatorSystemDefault,
0x6C,
0x0D,
0x38,
0xC3,
0x17,
0xF9,
0xE5,
0x9C,
0xB0,
0x93,
0x4E,
0xA7,
0x80,
0x9B,
0x09,
0xFB,
0x5D,
0xDD,
0xAC,
0x16,
0xA1,
0x40,
0x1D,
0x9A,
0xC0,
0x8D,
0xE2,
0x7A,
0xC6,
0x04,
0x7E,
)
}
}
@ -361,7 +379,7 @@ pub type IOUSBConfigurationDescriptorPtr = *mut IOUSBConfigurationDescriptor;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct IOUSBDeviceStruct500 {
pub struct IOUSBDeviceStruct650 {
pub _reserved: *mut ::std::os::raw::c_void,
pub QueryInterface: ::std::option::Option<
unsafe extern "C" fn(
@ -583,19 +601,48 @@ pub struct IOUSBDeviceStruct500 {
bandwidth: *mut UInt32,
) -> IOReturn,
>,
pub SetConfigurationV2: ::std::option::Option<
unsafe extern "C" fn(
self_: *mut ::std::os::raw::c_void,
configNum: UInt8,
startInterfaceMatching: bool,
issueRemoteWakeup: bool,
) -> IOReturn,
>,
pub RegisterForNotification: ::std::option::Option<
unsafe extern "C" fn(
self_: *mut ::std::os::raw::c_void,
notificationMask: UInt64,
callback: IOAsyncCallback2,
refCon: *mut ::std::os::raw::c_void,
pRegistrationToken: *mut UInt64,
) -> IOReturn,
>,
pub UnregisterNotification: ::std::option::Option<
unsafe extern "C" fn(
self_: *mut ::std::os::raw::c_void,
registrationToken: UInt64,
) -> IOReturn,
>,
pub AcknowledgeNotification: ::std::option::Option<
unsafe extern "C" fn(
self_: *mut ::std::os::raw::c_void,
notificationToken: UInt64,
) -> IOReturn,
>,
}
pub type IOUSBDeviceInterface500 = IOUSBDeviceStruct500;
pub type IOUSBDeviceInterface650 = IOUSBDeviceStruct650;
// Tweak: these are just function pointers to thread-safe functions,
// so add send and sync to the C-type. (Calling these from multiple threads
// may cause odd behavior on the USB bus, though, so we'll still want to wrap the
// device in Mutex somewhere up from here.)
unsafe impl Send for IOUSBDeviceInterface500 {}
unsafe impl Sync for IOUSBDeviceInterface500 {}
unsafe impl Send for IOUSBDeviceInterface650 {}
unsafe impl Sync for IOUSBDeviceInterface650 {}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct IOUSBInterfaceStruct500 {
pub struct IOUSBInterfaceStruct700 {
pub _reserved: *mut ::std::os::raw::c_void,
pub QueryInterface: ::std::option::Option<
unsafe extern "C" fn(
@ -998,11 +1045,124 @@ pub struct IOUSBInterfaceStruct500 {
bytesPerInterval: *mut UInt16,
) -> IOReturn,
>,
pub GetPipePropertiesV3: ::std::option::Option<
unsafe extern "C" fn(
self_: *mut ::std::os::raw::c_void,
pipeRef: UInt8,
properties: *mut IOUSBEndpointProperties,
) -> IOReturn,
>,
pub GetEndpointPropertiesV3: ::std::option::Option<
unsafe extern "C" fn(
self_: *mut ::std::os::raw::c_void,
properties: *mut IOUSBEndpointProperties,
) -> IOReturn,
>,
pub SupportsStreams: ::std::option::Option<
unsafe extern "C" fn(
self_: *mut ::std::os::raw::c_void,
pipeRef: UInt8,
supportsStreams: *mut UInt32,
) -> IOReturn,
>,
pub CreateStreams: ::std::option::Option<
unsafe extern "C" fn(
self_: *mut ::std::os::raw::c_void,
pipeRef: UInt8,
streamID: UInt32,
) -> IOReturn,
>,
pub GetConfiguredStreams: ::std::option::Option<
unsafe extern "C" fn(
self_: *mut ::std::os::raw::c_void,
pipeRef: UInt8,
configuredStreams: *mut UInt32,
) -> IOReturn,
>,
pub ReadStreamsPipeTO: ::std::option::Option<
unsafe extern "C" fn(
self_: *mut ::std::os::raw::c_void,
pipeRef: UInt8,
streamID: UInt32,
buf: *mut ::std::os::raw::c_void,
size: *mut UInt32,
noDataTimeout: UInt32,
completionTimeout: UInt32,
) -> IOReturn,
>,
pub WriteStreamsPipeTO: ::std::option::Option<
unsafe extern "C" fn(
self_: *mut ::std::os::raw::c_void,
pipeRef: UInt8,
streamID: UInt32,
buf: *mut ::std::os::raw::c_void,
size: UInt32,
noDataTimeout: UInt32,
completionTimeout: UInt32,
) -> IOReturn,
>,
pub ReadStreamsPipeAsyncTO: ::std::option::Option<
unsafe extern "C" fn(
self_: *mut ::std::os::raw::c_void,
pipeRef: UInt8,
streamID: UInt32,
buf: *mut ::std::os::raw::c_void,
size: UInt32,
noDataTimeout: UInt32,
completionTimeout: UInt32,
callback: IOAsyncCallback1,
refcon: *mut ::std::os::raw::c_void,
) -> IOReturn,
>,
pub WriteStreamsPipeAsyncTO: ::std::option::Option<
unsafe extern "C" fn(
self_: *mut ::std::os::raw::c_void,
pipeRef: UInt8,
streamID: UInt32,
buf: *mut ::std::os::raw::c_void,
size: UInt32,
noDataTimeout: UInt32,
completionTimeout: UInt32,
callback: IOAsyncCallback1,
refcon: *mut ::std::os::raw::c_void,
) -> IOReturn,
>,
pub AbortStreamsPipe: ::std::option::Option<
unsafe extern "C" fn(
self_: *mut ::std::os::raw::c_void,
pipeRef: UInt8,
streamID: UInt32,
) -> IOReturn,
>,
pub RegisterForNotification: ::std::option::Option<
unsafe extern "C" fn(
self_: *mut ::std::os::raw::c_void,
notificationMask: UInt64,
callback: IOAsyncCallback2,
refCon: *mut ::std::os::raw::c_void,
pRegistrationToken: *mut UInt64,
) -> IOReturn,
>,
pub UnregisterNotification: ::std::option::Option<
unsafe extern "C" fn(
self_: *mut ::std::os::raw::c_void,
registrationToken: UInt64,
) -> IOReturn,
>,
pub AcknowledgeNotification: ::std::option::Option<
unsafe extern "C" fn(
self_: *mut ::std::os::raw::c_void,
notificationToken: UInt64,
) -> IOReturn,
>,
pub RegisterDriver:
::std::option::Option<unsafe extern "C" fn(self_: *mut ::std::os::raw::c_void) -> IOReturn>,
}
pub type IOUSBInterfaceInterface700 = IOUSBInterfaceStruct700;
// Tweak: these are just function pointers to thread-safe functions,
// so add send and sync to the C-type. (Calling these from multiple threads
// may cause odd behavior on the USB bus, though, so we'll still want to wrap the
// device in Mutex somewhere up from here.)
unsafe impl Send for IOUSBInterfaceStruct500 {}
unsafe impl Sync for IOUSBInterfaceStruct500 {}
unsafe impl Send for IOUSBInterfaceInterface700 {}
unsafe impl Sync for IOUSBInterfaceInterface700 {}