I'm trying to use IOConnectCallStructMethod
so send data in the input field to talk to my driver in DriverKit (iPadOS)
In this particular method I send an input and I expect getting an output. But ignore the output for now.
In my case IOConnectCallStructMethod
is called with Swift:
var input:[UInt8] = Array(repeating: 0, count: 200)
for i in 0..<200 {
if (i % 2 == 0) {
input[i] = UInt8(i)
}
}
let arraySize:Int = input.count;
var outputSize = MemoryLayout<UInt8>.size * arraySize
var output:[UInt8] = Array(repeating: 0, count: arraySize)
let inputSize = MemoryLayout<UInt8>.size * input.count
let ret = IOConnectCallStructMethod(connection, Selector.mySelector.rawValue, &input, inputSize, &output, &outputSize)
This is the dispatch in the external method:
[ExternalMethodType_MyMethodRequest] =
{
.function = (IOUserClientMethodFunction) &Client::StaticHandleRequest,
.checkCompletionExists = false,
.checkScalarInputCount = 0,
.checkStructureInputSize = 200,
.checkScalarOutputCount = 0,
.checkStructureOutputSize = 200,
},
The ExternalMethod
gets called and when I try to access to the input data with this:
char* input = nullptr;
size_t length = 0;
if (arguments->structureInput != nullptr)
{
input = (char*)arguments->structureInput->getBytesNoCopy();
length = arguments->structureInput->getLength();
Log("Input: %s", input);
Log("length: %zu", length);
}
If I check the variable input
with a breakpoint the value is always ""
and the length is 200
I tried adding the input in a struct, same result.
I tried using IOConnectCallMethod
, same result.
The only alternative I can do it's making the input data extra big to force the system to use the descriptor instead of the OSData, but the input in this case would be always much smaller, so not sure if the best way to go.
Interestingly if I print the output of input with:
#define Log(fmt, ...) os_log(OS_LOG_DEFAULT, "NullDriver - " fmt "\n", ##__VA_ARGS__)
It will give me private
:
NullDriver - Input: <private>
Maybe the data is actually there but I can't see it?