I'm looking for a universal method to configure parameters from userspace agent to kernel since there is no Mac equivalent to windows registry where driver can directly access any key in this table using ZwQueryValueKey
command.
Therefore, I'd like to pass a dynamic list of variables through CFDictionary
.
In IOConnectCallMethod
there's a way to pass input pointer, but the question is if I can pass a CFDictionary
or CFDictionaryRef
instead of just a simple struct.
I saw that there are some IOkit commands that enable you to pass CFDictionaryRef directly, such as IOServiceGetMatchingService
but these are not intended for the driver module but for the entity that manages the drivers.
You can use the I/O Kit property mechanism to exchange plist-like data between user space and kernel space. For setting them from userspace, you'll want to use one or more of the following IOKitLib functions:
IORegistryEntrySetCFProperty
IORegistryEntrySetCFProperties
IOConnectSetCFProperty
IOConnectSetCFProperties
On the kernel side, your IOService or IOUserClient subclass should override the
virtual IOReturn setProperties( OSObject * properties );
function. Don't forget to treat any data received as potentially hostile, so make sure you check fornullptr
s, useOSDynamicCast()
when expecting concreteOSData
/OSNumber
/OSString
/OSArray
/etc. objects, and sanitise the data itself.Note that
setProperties()
does not automatically update the properties of theIORegistryEntry
object, you still need to callthis->setProperty()
for every property key/value key after it's been checked.Apple provides some basic high-level documentation for this mechanism too.