diff options
Diffstat (limited to 'vendor/sysinfo/src/apple/macos/ffi.rs')
-rw-r--r-- | vendor/sysinfo/src/apple/macos/ffi.rs | 295 |
1 files changed, 215 insertions, 80 deletions
diff --git a/vendor/sysinfo/src/apple/macos/ffi.rs b/vendor/sysinfo/src/apple/macos/ffi.rs index f884701d9..0b9c82cfa 100644 --- a/vendor/sysinfo/src/apple/macos/ffi.rs +++ b/vendor/sysinfo/src/apple/macos/ffi.rs @@ -1,105 +1,111 @@ // Take a look at the license at the top of the repository in the LICENSE file. -use core_foundation_sys::base::CFAllocatorRef; -use core_foundation_sys::dictionary::CFMutableDictionaryRef; -use core_foundation_sys::string::{CFStringEncoding, CFStringRef}; +use core_foundation_sys::base::{mach_port_t, CFAllocatorRef}; +use core_foundation_sys::dictionary::{CFDictionaryRef, CFMutableDictionaryRef}; +use core_foundation_sys::string::CFStringRef; -use libc::{c_char, c_void}; -#[cfg(not(feature = "apple-sandbox"))] -use libc::{mach_port_t, size_t}; +use libc::{c_char, kern_return_t}; -pub(crate) use crate::sys::ffi::*; +// Note: IOKit is only available on MacOS up until very recent iOS versions: https://developer.apple.com/documentation/iokit -#[cfg(not(feature = "apple-sandbox"))] -extern "C" { - // The proc_* PID functions are internal Apple APIs which are not - // allowed in App store releases as Apple blocks any binary using them. +#[allow(non_camel_case_types)] +pub type io_object_t = mach_port_t; + +#[allow(non_camel_case_types)] +pub type io_iterator_t = io_object_t; +#[allow(non_camel_case_types)] +pub type io_registry_entry_t = io_object_t; +#[allow(non_camel_case_types)] +pub type io_name_t = *const c_char; - // IOKit is only available on MacOS: https://developer.apple.com/documentation/iokit, and when not running inside - // of the default macOS sandbox. - pub fn IOMasterPort(a: i32, b: *mut mach_port_t) -> i32; +pub type IOOptionBits = u32; - pub fn IOServiceMatching(a: *const c_char) -> *mut c_void; +#[allow(non_upper_case_globals)] +pub const kIOServicePlane: &str = "IOService\0"; +#[allow(non_upper_case_globals)] +pub const kIOPropertyDeviceCharacteristicsKey: &str = "Device Characteristics"; +#[allow(non_upper_case_globals)] +pub const kIOPropertyMediumTypeKey: &str = "Medium Type"; +#[allow(non_upper_case_globals)] +pub const kIOPropertyMediumTypeSolidStateKey: &str = "Solid State"; +#[allow(non_upper_case_globals)] +pub const kIOPropertyMediumTypeRotationalKey: &str = "Rotational"; +// Note: Obtaining information about disks using IOKIt is allowed inside the default macOS App Sandbox. +#[link(name = "IOKit", kind = "framework")] +extern "C" { pub fn IOServiceGetMatchingServices( - a: mach_port_t, - b: *mut c_void, - c: *mut io_iterator_t, - ) -> i32; + mainPort: mach_port_t, + matching: CFMutableDictionaryRef, + existing: *mut io_iterator_t, + ) -> kern_return_t; pub fn IOIteratorNext(iterator: io_iterator_t) -> io_object_t; - pub fn IOObjectRelease(obj: io_object_t) -> i32; - - pub fn IOServiceOpen(device: io_object_t, a: u32, t: u32, x: *mut io_connect_t) -> i32; - - pub fn IOServiceClose(a: io_connect_t) -> i32; - - pub fn IOConnectCallStructMethod( - connection: mach_port_t, - selector: u32, - inputStruct: *const KeyData_t, - inputStructCnt: size_t, - outputStruct: *mut KeyData_t, - outputStructCnt: *mut size_t, - ) -> i32; - // pub fn IORegistryEntryCreateCFProperties( - // entry: io_registry_entry_t, - // properties: *mut CFMutableDictionaryRef, - // allocator: CFAllocatorRef, - // options: IOOptionBits, - // ) -> kern_return_t; - // pub fn IORegistryEntryGetName(entry: io_registry_entry_t, name: *mut c_char) -> kern_return_t; -} + pub fn IOObjectRelease(obj: io_object_t) -> kern_return_t; -extern "C" { - pub fn CFStringCreateWithCStringNoCopy( - alloc: *mut c_void, - cStr: *const c_char, - encoding: CFStringEncoding, - contentsDeallocator: *mut c_void, - ) -> CFStringRef; - - // Disk information functions are non-operational on iOS because of the sandboxing - // restrictions of apps, so they don't can't filesystem information. This results in - // mountedVolumeURLs and similar returning `nil`. Hence, they are MacOS specific here. - - pub fn DASessionCreate(allocator: CFAllocatorRef) -> DASessionRef; - - // pub fn DADiskCreateFromVolumePath( - // allocator: CFAllocatorRef, - // session: DASessionRef, - // path: CFURLRef, - // ) -> DADiskRef; - pub fn DADiskCreateFromBSDName( + pub fn IORegistryEntryCreateCFProperty( + entry: io_registry_entry_t, + key: CFStringRef, allocator: CFAllocatorRef, - session: DASessionRef, - path: *const c_char, - ) -> DADiskRef; - // pub fn DADiskGetBSDName(disk: DADiskRef) -> *const c_char; - - pub fn DADiskCopyDescription(disk: DADiskRef) -> CFMutableDictionaryRef; -} + options: IOOptionBits, + ) -> CFDictionaryRef; + pub fn IORegistryEntryGetParentEntry( + entry: io_registry_entry_t, + plane: io_name_t, + parent: *mut io_registry_entry_t, + ) -> kern_return_t; -pub type DADiskRef = *const __DADisk; -pub type DASessionRef = *const __DASession; + pub fn IOBSDNameMatching( + mainPort: mach_port_t, + options: u32, + bsdName: *const c_char, + ) -> CFMutableDictionaryRef; -// We need to wrap `DASessionRef` to be sure `System` remains Send+Sync. -pub struct SessionWrap(pub DASessionRef); - -unsafe impl Send for SessionWrap {} -unsafe impl Sync for SessionWrap {} + // This is deprecated as of macOS 12.0, but Rust doesn't have a good way to only use the replacement on 12+. + pub static kIOMasterPortDefault: mach_port_t; +} -#[cfg(not(feature = "apple-sandbox"))] +#[cfg(all( + not(feature = "apple-sandbox"), + any(target_arch = "x86", target_arch = "x86_64") +))] mod io_service { - use super::mach_port_t; + use super::{io_object_t, mach_port_t}; + use core_foundation_sys::dictionary::CFMutableDictionaryRef; + use libc::{c_char, kern_return_t, size_t, task_t}; #[allow(non_camel_case_types)] - pub type io_object_t = mach_port_t; - #[allow(non_camel_case_types)] pub type io_connect_t = io_object_t; + #[allow(non_camel_case_types)] - pub type io_iterator_t = io_object_t; + pub type io_service_t = io_object_t; + + #[allow(non_camel_case_types)] + pub type task_port_t = task_t; + + extern "C" { + pub fn IOServiceMatching(a: *const c_char) -> CFMutableDictionaryRef; + + pub fn IOServiceOpen( + device: io_service_t, + owning_task: task_port_t, + type_: u32, + connect: *mut io_connect_t, + ) -> kern_return_t; + + pub fn IOServiceClose(a: io_connect_t) -> kern_return_t; + + #[allow(dead_code)] + pub fn IOConnectCallStructMethod( + connection: mach_port_t, + selector: u32, + inputStruct: *const KeyData_t, + inputStructCnt: size_t, + outputStruct: *mut KeyData_t, + outputStructCnt: *mut size_t, + ) -> kern_return_t; + } #[cfg_attr(feature = "debug", derive(Debug, Eq, Hash, PartialEq))] #[repr(C)] @@ -143,8 +149,13 @@ mod io_service { pub bytes: [i8; 32], // SMCBytes_t } + #[allow(dead_code)] pub const KERNEL_INDEX_SMC: i32 = 2; + + #[allow(dead_code)] pub const SMC_CMD_READ_KEYINFO: u8 = 9; + + #[allow(dead_code)] pub const SMC_CMD_READ_BYTES: u8 = 5; pub const KIO_RETURN_SUCCESS: i32 = 0; @@ -153,4 +164,128 @@ mod io_service { #[cfg(feature = "apple-sandbox")] mod io_service {} +#[cfg(all( + not(feature = "apple-sandbox"), + any(target_arch = "x86", target_arch = "x86_64") +))] +pub use io_service::*; + +#[cfg(all(not(feature = "apple-sandbox"), target_arch = "aarch64"))] +mod io_service { + use std::ptr::null; + + use core_foundation_sys::array::CFArrayRef; + use core_foundation_sys::base::{CFAllocatorRef, CFRelease}; + use core_foundation_sys::dictionary::{ + kCFTypeDictionaryKeyCallBacks, kCFTypeDictionaryValueCallBacks, CFDictionaryCreate, + CFDictionaryRef, + }; + use core_foundation_sys::number::{kCFNumberSInt32Type, CFNumberCreate}; + use core_foundation_sys::string::{CFStringCreateWithCString, CFStringRef}; + + #[repr(C)] + pub struct __IOHIDServiceClient(libc::c_void); + + pub type IOHIDServiceClientRef = *const __IOHIDServiceClient; + + #[repr(C)] + pub struct __IOHIDEventSystemClient(libc::c_void); + + pub type IOHIDEventSystemClientRef = *const __IOHIDEventSystemClient; + + #[repr(C)] + pub struct __IOHIDEvent(libc::c_void); + + pub type IOHIDEventRef = *const __IOHIDEvent; + + #[allow(non_upper_case_globals)] + pub const kIOHIDEventTypeTemperature: i64 = 15; + + #[inline] + #[allow(non_snake_case)] + pub fn IOHIDEventFieldBase(event_type: i64) -> i64 { + event_type << 16 + } + + #[cfg(not(feature = "apple-sandbox"))] + extern "C" { + pub fn IOHIDEventSystemClientCreate(allocator: CFAllocatorRef) + -> IOHIDEventSystemClientRef; + + pub fn IOHIDEventSystemClientSetMatching( + client: IOHIDEventSystemClientRef, + matches: CFDictionaryRef, + ) -> i32; + + pub fn IOHIDEventSystemClientCopyServices(client: IOHIDEventSystemClientRef) -> CFArrayRef; + + pub fn IOHIDServiceClientCopyProperty( + service: IOHIDServiceClientRef, + key: CFStringRef, + ) -> CFStringRef; + + pub fn IOHIDServiceClientCopyEvent( + service: IOHIDServiceClientRef, + v0: i64, + v1: i32, + v2: i64, + ) -> IOHIDEventRef; + + pub fn IOHIDEventGetFloatValue(event: IOHIDEventRef, field: i64) -> f64; + } + + pub(crate) const HID_DEVICE_PROPERTY_PRODUCT: &[u8] = b"Product\0"; + + pub(crate) const HID_DEVICE_PROPERTY_PRIMARY_USAGE: &[u8] = b"PrimaryUsage\0"; + pub(crate) const HID_DEVICE_PROPERTY_PRIMARY_USAGE_PAGE: &[u8] = b"PrimaryUsagePage\0"; + + #[allow(non_upper_case_globals)] + pub(crate) const kHIDPage_AppleVendor: i32 = 0xff00; + + #[allow(non_upper_case_globals)] + pub(crate) const kHIDUsage_AppleVendor_TemperatureSensor: i32 = 0x0005; + + pub(crate) fn matching(page: i32, usage: i32) -> CFDictionaryRef { + unsafe { + let keys = [ + CFStringCreateWithCString( + null() as *const _, + HID_DEVICE_PROPERTY_PRIMARY_USAGE_PAGE.as_ptr() as *const _, + 0, + ), + CFStringCreateWithCString( + null() as *const _, + HID_DEVICE_PROPERTY_PRIMARY_USAGE.as_ptr() as *const _, + 0, + ), + ]; + + let nums = [ + CFNumberCreate(null(), kCFNumberSInt32Type, &page as *const _ as *const _), + CFNumberCreate(null(), kCFNumberSInt32Type, &usage as *const _ as *const _), + ]; + + let dict = CFDictionaryCreate( + null(), + &keys as *const _ as *const _, + &nums as *const _ as *const _, + 2, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks, + ); + + for key in keys { + CFRelease(key as _); + } + + for num in nums { + CFRelease(num as _); + } + + dict + } + } +} + +#[cfg(all(not(feature = "apple-sandbox"), target_arch = "aarch64"))] pub use io_service::*; |