Gain user-space access to hardware devices and drivers using IOKit.

Posts under IOKit tag

44 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

Programatically changing the brightness of your Macbook
Hi all, I was wondering if anyone knew a way to change the brightness of your MacBook screen in Swift without using an overlay that changes the colours? I want the effect of just pressing the F1 and F2 brightness controls but done without using system events/ Applescript popping up windows on the screen. I think the UIScreen.brightness is something similar to what I want but it is not available for NSscreen. I can't figure out a way to do it with IOKit either. Things like ddccl doesn't work as the screen is not an external monitor. If there is a solution using Swift or terminal commands any help is much appreciated. Thanks, James
1
0
231
4w
block all USB devices
Hello, I am working on app which must prevent attaching any USB devices to Mac due to security. Unfortunately I have not found any direct way to implement such blocking: Looks like IOKit does not allow to block USB (at least in user space) ES_EVENT_TYPE_AUTH_IOKIT_OPEN (Endpoint Security) does not prevent using USB device if I send response ES_AUTH_RESULT_DENY for "AppleUSBHostDeviceUserClient" I have found several similar problems on forum but no any solution: https://developer.apple.com/forums/thread/671193 (https://developer.apple.com/forums/thread/756573 https://developer.apple.com/forums/thread/741051 What is the easiest way to implement such blocking? Thank you in advance!
6
0
345
3w
How to Symbolicate an Apple Silicon Panic?
Investigating a kernel panic, I discovered that Apple Silicon Panic traces are not working with how I know to symbolicate the panic information. I have not found proper documentation that corrects this situation. Attached file is an indentity-removed panic, received from causing an intentional panic (dereferencing nullptr), so that I know what functions to expect in the call stack. This is cut-and-pasted from the "Report To Apple" dialog that appears after the reboot: panic_1_4_21_b.txt To start, I download and install the matching KDK (in this case KDK_14.6.1_23G93.kdk), identified from this line: OS version: 23G93 Kernel version: Darwin Kernel Version 23.6.0: Mon Jul 29 21:14:04 PDT 2024; root:xnu-10063.141.2~1/RELEASE_ARM64_T8122 Then start lldb from Terminal, using this command: bash_prompt % lldb -arch arm64e /Library/Developer/KDKs/KDK_14.6.1_23G93.kdk/System/Library/Kernels/kernel.release.t8122 Next I load the remaining scripts per the instructions from lldb: (lldb) settings set target.load-script-from-symbol-file true I need to know what address to load my kext symbols to, which I read from this line of the panic log, after the @ symbol: com.company.product(1.4.21d119)[92BABD94-80A4-3F6D-857A-3240E4DA8009]@0xfffffe001203bfd0->0xfffffe00120533ab I am using a debug build of my kext, so the DWARF symbols are part of the binary. I use this line to load the symbols into the lldb session: (lldb) addkext -F /Library/Extensions/KextName.kext/Contents/MacOS/KextName 0xfffffe001203bfd0 And now I should be able to use lldb image lookup to identify pointers on the stack that land within my kext. For example, the current PC at the moment of the crash lands within the kext (expected, because it was intentional): (lldb) image lookup -a 0xfffffe001203fe10 Which gives the following incorrect result: Address: KextName[0x0000000000003e40] (KextName.__TEXT.__cstring + 14456) Summary: "ffer has %d retains\n" That's not even a program instruction - that's within a cstring. No, that cstring isn't involved in anything pertaining to the intentional panic I am expecting to see. Can someone please explain what I'm doing wrong and provide instructions that will give symbol information from a panic trace on an Apple Silicon Mac? Disclaimers: Yes I know IOPCIFamily is deprecated, I am in process of transitioning to DriverKit Dext from IOKit kext. Until then I must maintain the kext. Terminal command "atos" provides similar incorrect results, and seems to not work with debug-built-binaries (only dSYM files) Yes this is an intentional panic so that I can verify the symbolicate process before I move on to investigating an unexpected panic I have set nvram boot-args to include keepsyms=1 I have tried (lldb) command script import lldb.macosx but get a result of error: no images in crash log (after the nvram settings)
4
0
405
2w
matching dictionary to find particular IOUSBInterface
Hello, I am trying to get value of InterfaceClass for particular USB Device. I modified matching dictionary and added the property locationID property. CFMutableDictionaryRef matchingDictionary = IOServiceMatching(kIOUSBInterfaceClassName); if (!matchingDictionary) { return -1; } int32_t locationID = 0xffff; CFNumberRef cfLocationID = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &locationID); CFDictionaryAddValue(matchingDictionary, CFSTR(kUSBHostPropertyLocationID), cfLocationID); CFRelease(cfLocationID); io_service_t ioService = IOServiceGetMatchingService(kIOMasterPortDefault, matchingDictionary); if (!ioService) { return -1; } CFNumberRef cfInterfaceClass = (CFNumberRef)IORegistryEntrySearchCFProperty(ioService, kIOServicePlane, CFSTR(kUSBHostMatchingPropertyInterfaceClass), kCFAllocatorDefault, kNilOptions); ... Unfortunately nothing is found and ioService is NULL. What can be wrong here? Thank you in advance!
2
0
285
Aug ’24
How to implement NVMESMARTLib for USB-NVMe bridge chip?
Many USB storage devices are NVMe devices accessed through a USB-NVMe bridge chip, such as those by JMicron and Asmedia. These chipsets do not forward SMART data requests to the devices, but do have the capability to forward raw NVMe commands to the devices using vendor specific requests. How can we provide access to SMART data for NVMe devices accessed through a bridge chip like this? Many people used the OSX SAT SMART kext driver to provide access to SMART data for devices using USB-SATA chips, but it is a kext and doesn't support NVMe. See https://binaryfruit.com/drivedx/usb-drive-support#install-instructions Would we need to implement a kext like that to make this work? Is there a DriverKit way to do this?
4
0
547
Jul ’24
Low-level event-posting help needed.
Hi there, I am working on a little application which processes cursor and graphics tablet data and adds some extra control to the output. So far it makes use of... if let eventTap = CGEvent.tapCreate(tap: .cgSessionEventTap, //.cghidEventTap place: .headInsertEventTap, options: .defaultTap, eventsOfInterest: eventMask, callback: handleTapEvent, userInfo: userInfo) ... to modify existing events. The issue that in some cases arises (it's a globally working app) - that some other applications pull and process pointer-data aside the event stream and therefor create conflicting values. Would creating and posting events to a 'virtual pointing device' on a lower system level (kext) help? Let's discuss. BR, E
0
0
251
Jul ’24
"SYSTEM EXTENSION" entitlements in framework
Hello everyone! I'm developing framework and app for macOS for PCI devices. For communication with driverkit, I'm verifying by giving userclient access entities of system extension to app. However, the app is just a sample program, and our customer is trying to develop the app using a framework with PCI communication part. Is there a way to build a framework with my company's signature, and to build and execute it without acquiring userclient access elements by any chance by a customer developer? Moreover, userclient access is only available to developers who have subscribed to the Apple Developer Program, so I hope that client/developers do not need to obtain separate entries.
3
0
500
Jul ’24
Access NVMe SMART on iPad
When using external NVMe devices on iOS / iPadOS I cannot tell how to access the disk SMART data. On macOS I can use NVMeSMARTLibExternal.h to access this information but the same system does not seem to work on iPadOS (even with Thunderbolt NVMe devices). When using M series iPads with professional Thunderbolt storage this woudlbe very useful.
2
0
445
Jul ’24
Proper way to use IOKit in iOS app?
Hello, forum, I'm trying to build connection between a non-MFi HID device (like keyboard) and iOS app with IOKit and Swift. Thanks to this post, I have manage to import the IOKit into objc header. IOKit on iOS/iPadOS 16.0+ #import <IOKit/IOKitLib.h> However, I have this compiler error when I try to imitate same methods in the SerialPortSaple project from following article, but the IOKit can not be imported to Swift at first place. Communicating with a Modem on a Serial Port The screen shot of the sample project: It looks like the complier unable to reach the io_object_t type somehow, is there any workaround or approach?
4
0
756
Jun ’24
How to get Magic Mouse/Trackpad InputValueCallback
I confirmed that I had successfully turned on the device and registered the callback method, but the callback method was not successfully invoked when moving with Magic mouse. What method does the Magic Mouse and Magic Trackpad need to use to get the input value of the device? IOReturn ioReturn = IOHIDDeviceOpen(deviceRef, kIOHIDOptionsTypeNone); if ( kIOReturnSuccess == ioReturn ) { IOHIDDeviceRegisterInputValueCallback(deviceRef, mouseInputValueCallback, NULL); } static void mouseInputValueCallback(void *context, IOReturn result, void *sender, IOHIDValueRef value) { NSLog(@"handle input value"); } I passed the __IOHIDDeviceCopyMatchingInputElements get magic mouse input element <__NSArrayM 0x6000012c4900>( timestamp: 0 type: 1 usagePage: 1 usage: 48 reportID: 16 value: 0, timestamp: 0 type: 1 usagePage: 1 usage: 49 reportID: 16 value: 0, timestamp: 0 type: 2 usagePage: 9 usage: 1 reportID: 16 value: 0, timestamp: 0 type: 2 usagePage: 9 usage: 2 reportID: 16 value: 0 ) (NSArray *)getHIDReprots { if (!deviceRef) { return nil; } NSMutableArray *reports = [[NSMutableArray alloc] init]; CFArrayRef elements; CFIndex i; elements = IOHIDDeviceCopyMatchingElements(deviceRef, NULL, kIOHIDOptionsTypeNone); for (i = 0; i<CFArrayGetCount(elements); i++) { const IOHIDElementRef element = (void*)CFArrayGetValueAtIndex(elements, i); IOHIDElementType eleType = IOHIDElementGetType(element); NSString *eleTypeStr = @""; switch (eleType) { case kIOHIDElementTypeInput_Misc: eleTypeStr = @"kIOHIDElementTypeInput_Misc"; break; case kIOHIDElementTypeInput_Button: eleTypeStr = @"kIOHIDElementTypeInput_Button"; break; case kIOHIDElementTypeInput_Axis: eleTypeStr = @"kIOHIDElementTypeInput_Axis"; break; case kIOHIDElementTypeInput_ScanCodes: eleTypeStr = @"kIOHIDElementTypeInput_ScanCodes"; break; case kIOHIDElementTypeInput_NULL: eleTypeStr = @"kIOHIDElementTypeInput_NULL"; break; case kIOHIDElementTypeOutput: eleTypeStr = @"kIOHIDElementTypeOutput"; break; case kIOHIDElementTypeFeature: eleTypeStr = @"kIOHIDElementTypeFeature"; break; case kIOHIDElementTypeCollection: eleTypeStr = @"kIOHIDElementTypeCollection"; break; default: break; } uint32_t page = IOHIDElementGetUsagePage(element); uint32_t usage = IOHIDElementGetUsage(element); uint32_t reportID = IOHIDElementGetReportID(element); uint32_t reportSize = IOHIDElementGetReportSize(element); uint32_t reportCount = IOHIDElementGetReportCount(element); NSString *elementStr = [[NSString alloc] initWithFormat:@" reportID:%d, reportSize:%d, type:%@, UsagePage:%d, usage:%d, reportCount:%d\n\n",reportID, reportSize, eleTypeStr, page, usage, reportCount]; [reports addObject:elementStr]; } return reports; } reportID:0, reportSize:0, type:kIOHIDElementTypeCollection, UsagePage:1, usage:2, reportCount:1 reportID:0, reportSize:0, type:kIOHIDElementTypeCollection, UsagePage:1, usage:1, reportCount:1 reportID:16, reportSize:16, type:kIOHIDElementTypeInput_Misc, UsagePage:1, usage:48, reportCount:1 reportID:16, reportSize:16, type:kIOHIDElementTypeInput_Misc, UsagePage:1, usage:49, reportCount:1 reportID:16, reportSize:1, type:kIOHIDElementTypeInput_Button, UsagePage:9, usage:1, reportCount:1 reportID:16, reportSize:1, type:kIOHIDElementTypeInput_Button, UsagePage:9, usage:2, reportCount:1 reportID:71, reportSize:8, type:kIOHIDElementTypeFeature, UsagePage:6, usage:32, reportCount:1 reportID:85, reportSize:512, type:kIOHIDElementTypeFeature, UsagePage:65282, usage:85, reportCount:64 reportID:0, reportSize:0, type:kIOHIDElementTypeInput_NULL, UsagePage:0, usage:-1, reportCount:1 reportID:0, reportSize:1, type:kIOHIDElementTypeInput_NULL, UsagePage:0, usage:0, reportCount:1 reportID:16, reportSize:0, type:kIOHIDElementTypeInput_NULL, UsagePage:0, usage:-1, reportCount:1 reportID:16, reportSize:1, type:kIOHIDElementTypeInput_NULL, UsagePage:0, usage:0, reportCount:1 reportID:71, reportSize:0, type:kIOHIDElementTypeInput_NULL, UsagePage:0, usage:-1, reportCount:1 reportID:71, reportSize:1, type:kIOHIDElementTypeInput_NULL, UsagePage:0, usage:0, reportCount:1 reportID:85, reportSize:0, type:kIOHIDElementTypeInput_NULL, UsagePage:0, usage:-1, reportCount:1 reportID:85, reportSize:1, type:kIOHIDElementTypeInput_NULL, UsagePage:0, usage:0, reportCount:1 Devices: VendorID ProductID LocationID UsagePage Usage RegistryID Transport Class Product UserClass Built-In 0x4c 0x265 0x3bab3ec3 1 2 0x100001ec4 Bluetooth AppleHSBluetoothHIDDriver Magic Trackpad (null) 0 0x4c 0x265 0x3bab3ec3 0 1 0x100001eb2 Bluetooth AppleHSBluetoothDevice Magic Trackpad (null) 0 0x5ac 0x30d 0x5abbb32b 1 2 0x100001221 Bluetooth BNBMouseDevice Magic Mouse (null) 0 0x4c 0x265 0x3bab3ec3 65280 3 0x100001ed2 Bluetooth AppleHSBluetoothHIDDriver Magic Trackpad (null) 0 0x4c 0x265 0x3bab3ec3 65280 13 0x100001ecc Bluetooth AppleHSBluetoothHIDDriver Magic Trackpad (null) 0 0x4c 0x265 0x3bab3ec3 65280 11 0x100001eba Bluetooth AppleHSBluetoothHIDDriver Magic Trackpad (null) 0
5
0
558
Jun ’24
Block iOS device from being mounted on mac.
Hello. Is there a legal way to block iOS devices from being mounted on macOS? I noticed, that when an iOS device is connected, it pretends to be like a storage device but it is not. It not even going through diskArbitration. It seems that some fileProvider is taking place there. I know that it is possible to do via the MDM profile: <key>PayloadContent</key> <dict> <key>.GlobalPreferences</key> <dict> <key>Forced</key> <array> <dict> <key>mcx_preference_settings</key> <dict> <key>ignore-devices</key> <true/> </dict> </dict> </array> </dict> </dict> But is there some programmatic solution? If I use EndpointSecurity and block file operations for the usbmuxd process on /var folder, it prevents iOS devices from being mounted. But wouldn't be there any negative side effects from such a solution?
1
0
772
May ’24
App sandbox extension revoked on Ventura
Hi everyone, first-time caller, long-ti... wait, no, I just got here. :) I am relatively new to all things Apple, so apologies in advance if it takes me a few goes to properly explain things. We have a framework, which includes an API, an XPC service, etc, and we have a device driver. We also have some sample apps that use the framework, and if they have the app sandbox capability, then we expect them to use the XPC Service instead of accessing our driver directly. This works fine on Monterey and presumably has worked fine on all previous versions of MacOS. Something seems to have changed on Ventura, and we don't understand what. When we build the same app on Ventura, it appears to be in the sandbox (according to the Sandbox column in Activity Monitor), but in the Console there is this line (twice): default <time> <OurAppName> Revoking sandbox extension; key = 0 Which we suspect is linked to the fact that the app then does not use the XPC Service, and instead accesses the driver directly, much to our surprise. Software built on developer's machines is "Automatically managed" and "Signed to Run Locally" in case that matters. Do we need to change our code to support Ventura and onward? Or is it a bizarre bug? Oh, I should say that I'm running the latest version of Ventura (13.6.7 as of writing) but not the latest Xcode (14.2 (14C18)) and CLI tools... can't remember how to find that version... Apple clang version 14.0.0 (clang-1400.0.29.202). Any help would be appreciated, thanks. Jeremy
6
0
624
May ’24
internal and external USB device list
Using IOServiceMatching and IOServiceGetMatchingServices api's written in swift to extract the info of both internal and external USB devices connected. For the same code Intel based Mac OS devices gives all the info like product id , vendor id , Serial number and etc for both external and Internal USB devices( Apple and Non Apple devices connected either to Apple T2 bus or USB bus). For the same code M2 Mac Machine only gives the external device info which are connected to USB, doesn't give any info of Internal USB connected devices. Why is this difference ? Which api's need to be used to extract info of internal USB connected devices even in M2 based Mac machine. Thanks
3
0
528
Apr ’24
Tracking bluetooth connection from macOS to non-Apple smartphones
Hi! I am trying to figure out whether there are any ways to get notifications when a macOS user connects to another device via Bluetooth (specifically when a smartphone is paired with a MacBook). I know about IOBluetooth, but it seems like you have to send periodic queries for devices when using this framework, and there is no general way to receive such notifications. I know that IOHIDManager may help to track connection with human interface devices such as keyboards, trackpads, joysticks, etc. But is there any API in IOKit/DriverKit that could help get notifications when a macOS user connects to a smartphone? Maybe I am missing an important part of IOBluetooth, so I would appreciate any help.
0
0
459
Apr ’24
How to communicate with smart card readers conncetd to USB-C port in iOS?
Hello All, I am new to iOS development and would like to detect the smart card readers connected to USB-C port on iOS (16+) devices. The smart card reader is a custom hardware and not MFi certified. So as per my understanding, I cannot use ExternalAccessory.framework without MFi certification. Correct? How else can I achieve this? Does TKSmartCardSlotManager works for this purpose (or is it only for NFC devices?)? Is there any example for how to use this interface? I couldn't find any example for this as a starting point... Thanks in advance.
4
0
1k
Jun ’24
Sanitize and other commands for External SSD Media
I am trying to implement the Sanitize and Firmware Upgrade commands for an external card connected via the Thunderbolt Interface (4.0) Should we consider writing a Kext based off IOBlockStorageDriver or IOPCI interface. NVMController does not expose anything more than the 3 API.. SmartReadData, getLogData and getIdentifyData. The device is connected only on MacOS.(mini and macbooks) My ioregistry look like : | | | +-o DSB1@1 <class IOPCIDevice, id 0x1000003dc, registered, matched, active, busy 0 (194 ms), retain 14> | | | | +-o IOPP <class IOPCI2PCIBridge, id 0x100000457, registered, matched, active, busy 0 (182 ms), retain 8> | | | | +-o UPS0@0 <class IOPCIDevice, id 0x1000003e0, registered, matched, active, busy 0 (182 ms), retain 17> | | | | +-o IOPP <class IOPCI2PCIBridge, id 0x100000477, registered, matched, active, busy 0 (181 ms), retain 8> | | | | +-o pci-bridge@0 <class IOPCIDevice, id 0x1000003e1, registered, matched, active, busy 0 (181 ms), retain 11> | | | | +-o IOPP <class IOPCI2PCIBridge, id 0x10000047d, registered, matched, active, busy 0 (180 ms), retain 8> | | | | +-o pci1987,5021@0 <class IOPCIDevice, id 0x1000003e2, registered, matched, active, busy 0 (180 ms), retain 12> | | | | +-o IONVMeController <class IONVMeController, id 0x100000486, registered, matched, active, busy 0 (166 ms), retain 11> | | | | +-o IONVMeBlockStorageDevice@1 <class IONVMeBlockStorageDevice, id 0x10000048c, registered, matched, active, busy 0 (166 ms), retain 11> | | | | +-o IOBlockStorageDriver <class IOBlockStorageDriver, id 0x10000048d, registered, matched, active, busy 0 (166 ms), retain 8> | | | | +-o Prograde Digital Media <class IOMedia, id 0x10000048e, registered, matched, active, busy 0 (166 ms), retain 12> | | | | +-o IOMediaBSDClient <class IOMediaBSDClient, id 0x100000490, registered, matched, active, busy 0 (0 ms), retain 6> | | | | +-o IOGUIDPartitionScheme <class IOGUIDPartitionScheme, id 0x100000492, !registered, !matched, active, busy 0 (0 ms), retain 7> | | | | +-o EFI System Partition@1 <class IOMedia, id 0x1000004d7, registered, matched, active, busy 0 (0 ms), retain 10> | | | | | +-o IOMediaBSDClient <class IOMediaBSDClient, id 0x1000004db, registered, matched, active, busy 0 (0 ms), retain 6> | | | | +-o Untitled 2@2 <class IOMedia, id 0x1000004d9, registered, matched, active, busy 0 (0 ms), retain 11> | | | | +-o IOMediaBSDClient <class IOMediaBSDClient, id 0x1000004df, registered, matched, active, busy 0 (0 ms), retain 7>Any pointers on this would be helpful.
0
0
487
Mar ’24
How to properly convert any size of application memory into the kernel space of Driverkit?
Hardware and software configuration MacBook Air M2 2022 16GB, MacOS Ventura 13.2.1 Full description This is a DriverKit that controls PCIE FPGA devices for low-latency data exchange. This driver has been implemented on Iokit, and now it needs to be launched on Driverkit to adapt to newer Macs. Driverkit lacks the IOMemoryDescriptor::withAddressRange(Iokit) function to convert the app's memory of any size to a Descriptor. Currently, we use args->structureOutputDescriptor->CreateMapping to map the Descriptor passed by the application to the kernel layer. // App size_t ***::xxRead(long long addr, size_t size, void * buff){ std::lock_guard<std::mutex> guard(usrLock); kern_return_t kr; uint64_t info[2] = {(uint64_t)addr, (uint64_t)size}; kr = IOConnectCallMethod( connect, kUserReadIO, info, 2, NULL, NULL, NULL, NULL, buff, &size); return size; } // Driverkit const IOUserClientMethodDispatch sMethods[kNumMethods] = { [kUserReadIO] = { (IOUserClientMethodFunction) &SmiPcieUc::sUserReadIo, .checkCompletionExists = false, .checkScalarInputCount = 2, // Read Addr, size .checkStructureInputSize = 0, .checkScalarOutputCount = 0, .checkStructureOutputSize = kIOUserClientVariableStructureSize} // Read Data }; kern_return_t SmiPcieUc::sUserReadIo (OSObject * target, void* reference, IOUserClientMethodArguments* args){ IOMemoryMap * memMap = nullptr; uint32_t * buffKptr = nullptr; kern_return_t rt = 0; if(target == nullptr){ Log("***Err***: sUserReadIo Target is Null!"); return kIOReturnError; } if(args->structureOutputDescriptor){ rt = args->structureOutputDescriptor->CreateMapping(0,0,0,0,0, &memMap); if(rt == kIOReturnSuccess){ buffKptr = reinterpret_cast<uint32_t *>(memMap->GetAddress()); } else { Log("***Err***: sUserReadIo Mapping Failed!"); return kIOReturnNoMemory; } } else { buffKptr = (uint32_t *) args->structureOutput; } rt = ((SmiPcieUc *)target)->UserReadIo((uint64_t *)&args->scalarInput[0], (size_t *)&args->scalarInput[1], buffKptr); OSSafeReleaseNULL(memMap); return rt; } phenomenon When StructureOutputSize is greater than 4096, args>structureOutputDescriptor exists, and when it is less than or equal to 4096, args->structureOutputDescriptor and args->structureOutput are both equal to nullptr, (in IOkit, args->structureOutput is not empty)。 How to properly convert any size of application memory into the kernel space of Driverkit?
1
0
618
Mar ’24
monitor input events
Hello, I need to monitor input events and convert keycode to symbol. E.g. convert kHIDUsage_KeyboardQ to symbol according to used keyboard layout. Are there any API to get current keyboard layout (language) in C++? If I understand correctly, the API TISGetInputSourceProperty() is deprecated. Are there any way to monitor keyboard layout changed? (some system notification in case of keyboard layout change) Are there any way to translate keycode to symbol except UCKeyTranslate() which is part of deprecated Unicode Utilities? Thank you in advance.
1
0
533
Feb ’24
smc keys for M3 pro chip, returning temperature values
Im honestly a bit lost and looking for general pointers. Here is the general flow of my project. I have an Xcode project where I want to return and convert the temperature values accessed from the apple smc and I found a GitHub repo with all the smc key sensors for the M3Pros/Max chips: https://github.com/exelban/stats/issues/1703 basically, I have all these keys stored in an array in obj-c like so: NSArray *smcKeys = @[ @"Tp01", @"Tp05", @"Tp09", @"Tp0D", @"Tp0b", @"Tp0f", @"Tp0j", @"Tp0n",@"Tp0h", @"Tp0L", @"Tp0S", @"Tp0V", @"Tp0z", @"Tp0v", @"Tp17", @"Tp1F", @"Tp1J", @"Tp1p", @"Tp1h", @"Tp1R", ]; I am passing all these keys by passing 'smcKeys' in a regular C code file I have here that is meant to open, close and read the data shown here: #include "smc.h" #include <mach/mach.h> #include <IOKit/IOKitLib.h> #include "smckeys.h" io_connect_t conn; kern_return_t openSMC(void) { kern_return_t result; kern_return_t service; io_iterator_t iterator; service = IOServiceGetMatchingServices(kIOMainPortDefault, IOServiceMatching("AppleSMC"), &iterator); if(service == 0) { printf("error: could not match dictionary"); return 0; } result = IOServiceOpen(service, mach_task_self(), 0, &conn); IOObjectRelease(service); return 0; } kern_return_t closeSMC(void) { return IOServiceClose(conn); } kern_return_t readSMC(char *smcKeys, SMCVal_t *val) { kern_return_t result; uint32_t keyCode = *(uint32_t *)smcKeys; SMCVal_t inputStruct; SMCVal_t outputStruct; inputStruct.datasize = sizeof(SMCVal_t); inputStruct.datatype = 'I' << 24; //a left shift operation. turning the I into an int by shifting the ASCII value 24 bits to the left inputStruct.data[0] = keyCode; result = IOConnectCallStructMethod(conn, 5, &inputStruct, sizeof(SMCVal_t), &outputStruct, (size_t*)&inputStruct.datasize); if (result == kIOReturnSuccess) { if (val -> datasize > 0) { if (val -> datatype == ('f' << 24 | 'l' << 16 | 't' << 8 )) { //bit shifting to from 32bit operation associated with the ASCII charecters'f', 'l', and 't', sets datatype field. double temp = *(double *)val -> data; return temp; } } } return 0.0; } Which I am then then calling the functions from this file in a swift file and converting the values to Fahrenheit but no data is being printed in my console: import IOKit public class getTemperature { public struct SMCVal_t { var datasize: UInt32 var datatype: UInt32 var data: (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8) } @_silgen_name("openSMC") func openSMC() -> kern_return_t @_silgen_name("closeSMC") func closeSMC() -> kern_return_t @_silgen_name("readSMC") func readSMC(key: UnsafePointer<CChar>?,val: UnsafeMutablePointer<SMCVal_t>) -> kern_return_t func convertAndPrintTempValue(key:UnsafePointer<CChar>?,scale: Character, showTemp: Bool ) -> kern_return_t { let openSM = openSMC() guard openSM == 0 else { print("Failed to open SMC: \(openSM)") return kern_return_t() } let closeSM = closeSMC() guard closeSM == 0 else { print("could not close SMC: \(closeSM)") return IOServiceClose(conn) } func convertAndPrint(val: SMCVal_t) -> Double { if val.datatype == (UInt32("f".utf8.first!) << 24 | UInt32("l".utf8.first!) << 16 | UInt32("t".utf8.first!) << 8) { let extractedTemp = Double(val.data.0) return( extractedTemp * 9.0 / 5.0 + 32.0 ) } return 0.0 } let smcValue = SMCVal_t(datasize: 0, datatype: 0, data: (0,0,0,0,0,0,0,0)) let convertedVal = convertAndPrint(val: smcValue) print("Temperarure:\(convertedVal)F°") return kern_return_t() } } I know this is a lot but I am honestly looking for any tips to fill in any gaps in my knowledge for anyone who's built a similar application meant to extract any sort of data from Mac hardware.
1
0
646
Feb ’24