We inspired by announce that DriverKit will come to iPadOs this fall and decided to experiment with DriverKit on macOS.
We started from scratch but followed all the recommendations from Sample.
With our installer code we can:
- Install driver extension to macOS system. (
systemextensionsctl list
shows [activated enabled]) for our driver - See driver record using
ioreg
. So it's displayed: MyDriver <class IOUserService, id 0x10000193b, registered, matched, active, busy 0 (0 ms), retain 7> - See *.MyDriver process in Activity Monitor
In client code we can find a match:
private let dextIdentifier = "MyDriver"
private var lastResult: kern_return_t = kIOReturnSuccess
private var connection: io_connect_t = IO_OBJECT_NULL
var iterator: io_iterator_t = IO_OBJECT_NULL
var driver: io_service_t = IO_OBJECT_NULL
lastResult = IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceNameMatching(dextIdentifier), &iterator)
print("Search for services ...")
while case let service = IOIteratorNext(iterator),
service != IO_OBJECT_NULL {
driver = service
}
IOObjectRelease(iterator)
guard driver != IO_OBJECT_NULL else { return }
So driver
is not IO_OBJECT_NULL
. But we stuck on IOServiceOpen
. So code:
lastResult = IOServiceOpen(driver, mach_task_self_, UInt32(kIOHIDServerConnectType), &connection);
validateLastResult(forOperation: "opening service")
prints opening service: (iokit/common) general error
since IOServiceOpen
returns 0x2bc
What we tried:
- Disable SIP in recovery mode and set
systemextensionsctl developer on
Result: opening service: (iokit/common) general error
- Add
com.apple.developer.driverkit.userclient-access
to our client App.
Result: App crashes on start and in Console we see: taskgated-helper - Unsatisfied entitlements: com.apple.developer.driverkit.userclient-access
. We requested this entitlement.
- We found post were
com.apple.developer.driverkit.allow-any-userclient-access
suggested as solution.
Result: Driver extension is not started and we see in Console:
taskgated-helper MyDriver: Unsatisfied entitlements: com.apple.developer.driverkit.allow-any-userclient-access
amfid /Library/SystemExtensions/B7624EEF-3688-4735-A58B-26FEF4DE353C/MyDriver.dext/MyDriver signature not valid: -67671
- We recreated appIds, profiles on developer account that has
com.apple.developer.driverkit.allow-any-userclient-access
from Apple.
Result: Driver extension is started but we still see opening service: (iokit/common) general error
- We modified CommunicatingBetweenADriverKitExtensionAndAClientApp.zip by setting our appIds and profiles and run in in SIP disabled mode.
Result: opening service: (iokit/common) general error
Our environment:
macOS Monterey 12.4
XCode Version 13.4 (13F17a)
Driver Code is pretty straightforward:
///// iig
class MyDriver: public IOUserClient
{
public:
virtual bool init(void) override;
virtual kern_return_t Start(IOService * provider) override;
virtual kern_return_t Stop(IOService* provider) override;
virtual void free(void) override;
};
///// cpp
#define Log(fmt, ...) os_log(OS_LOG_DEFAULT, "MyDriver - " fmt "\n", ##__VA_ARGS__)
struct MyDriver_IVars {
OSAction* callbackAction = nullptr;
};
bool MyDriver::init() {
bool result = false;
Log("init()");
result = super::init();
if (result != true)
{
Log("init() - super::init failed.");
goto Exit;
}
ivars = IONewZero(MyDriver_IVars, 1);
if (ivars == nullptr)
{
Log("init() - Failed to allocate memory for ivars.");
goto Exit;
}
Log("init() - Finished.");
return true;
Exit:
return false;
}
kern_return_t
IMPL(MyDriver, Start)
{
kern_return_t ret;
ret = Start(provider, SUPERDISPATCH);
if(ret != kIOReturnSuccess) {
Log("Start() - super::Start failed with error: 0x%08x.", ret);
goto Exit;
}
ret = RegisterService();
if (ret != kIOReturnSuccess)
{
Log("Start() - Failed to register service with error: 0x%08x.", ret);
goto Exit;
}
Log("Start() - Finished.");
ret = kIOReturnSuccess;
Exit:
return ret;
}
kern_return_t
IMPL(MyDriver, Stop)
{
kern_return_t ret = kIOReturnSuccess;
Log("Stop()");
ret = Stop(provider, SUPERDISPATCH);
if (ret != kIOReturnSuccess)
{
Log("Stop() - super::Stop failed with error: 0x%08x.", ret);
}
return ret;
}
void MyDriver::free(void)
{
Log("free()");
IOSafeDeleteNULL(ivars, MyDriver_IVars, 1);
super::free();
}