5

I know how to send data to DriverKit and get back some values, that is application calling IOConnectCallStructMethod() and driver fill the OSData in structureOutput from application.

In my Application it is using IOConnectCallAsyncScalarMethod() and the kext using sendAsyncResult64() to let the app know events coming in. However the method sendAsyncResult64() is not available in DriverKit.

I saw AsyncCompletion looks like solution but no idea to implement it. Anyone know how to do? Appreciate if any suggestion!

pmdj
  • 22,018
  • 3
  • 52
  • 103
Vannes Yang
  • 141
  • 6
  • By the way in my app I use `IOConnectCallStructMethod` and prepares a buffer for driver, and in my driver use `IOMemoryDescriptor::CreateMapping` to fill related data let app get it. But I don't know how to use `IOMemoryDescriptor::CreateMapping` in successful way. – Vannes Yang Aug 26 '20 at 08:30

1 Answers1

6

IOUserClient::AsyncCompletion is indeed the replacement for sendAsyncResult64().

To call it successfully, you need to retain the OSAction object supplied in the completion field of the IOUserClientMethodArguments supplied in your ExternalMethod dispatch function. Then, when you are ready to send an asynchronous result, call

userclient->AsyncCompletion(saved_osaction, result, async_arguments, num_async_arguments);

Don't forget to release the OSAction object once you no longer need it. The array of async arguments will be passed to the handler function in the user space application, same as with a kext calling sendAsyncResult64().

Note that you can't asynchronously fill "small" structureOutput fields (4096 bytes or less) as these must be returned in the ExternalMethod handler. Only if the buffer is large enough to be passed via structureOutputDescriptor can you retain that descriptor and fill it with data after the initial ExternalMethod returns. This is no different than for kexts, however.

pmdj
  • 22,018
  • 3
  • 52
  • 103