blob: 0b9c82cfaea55a804b44e2e6340094074ed9d5c5 [file] [log] [blame]
// Take a look at the license at the top of the repository in the LICENSE file.
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, kern_return_t};
// Note: IOKit is only available on MacOS up until very recent iOS versions: https://developer.apple.com/documentation/iokit
#[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;
pub type IOOptionBits = u32;
#[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(
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) -> kern_return_t;
pub fn IORegistryEntryCreateCFProperty(
entry: io_registry_entry_t,
key: CFStringRef,
allocator: CFAllocatorRef,
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 fn IOBSDNameMatching(
mainPort: mach_port_t,
options: u32,
bsdName: *const c_char,
) -> CFMutableDictionaryRef;
// 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(all(
not(feature = "apple-sandbox"),
any(target_arch = "x86", target_arch = "x86_64")
))]
mod io_service {
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_connect_t = io_object_t;
#[allow(non_camel_case_types)]
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)]
pub struct KeyData_vers_t {
pub major: u8,
pub minor: u8,
pub build: u8,
pub reserved: [u8; 1],
pub release: u16,
}
#[cfg_attr(feature = "debug", derive(Debug, Eq, Hash, PartialEq))]
#[repr(C)]
pub struct KeyData_pLimitData_t {
pub version: u16,
pub length: u16,
pub cpu_plimit: u32,
pub gpu_plimit: u32,
pub mem_plimit: u32,
}
#[cfg_attr(feature = "debug", derive(Debug, Eq, Hash, PartialEq))]
#[repr(C)]
pub struct KeyData_keyInfo_t {
pub data_size: u32,
pub data_type: u32,
pub data_attributes: u8,
}
#[cfg_attr(feature = "debug", derive(Debug, Eq, Hash, PartialEq))]
#[repr(C)]
pub struct KeyData_t {
pub key: u32,
pub vers: KeyData_vers_t,
pub p_limit_data: KeyData_pLimitData_t,
pub key_info: KeyData_keyInfo_t,
pub result: u8,
pub status: u8,
pub data8: u8,
pub data32: u32,
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;
}
#[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::*;