2 * Copyright (c) 2019-2019 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
31 #include <IOKit/IOUserClient.h>
35 #ifndef _IOKIT_UIOUSERCLIENT_H
36 #define _IOKIT_UIOUSERCLIENT_H
38 #include <DriverKit/OSAction.iig>
39 #include <DriverKit/IOService.iig>
40 #include <DriverKit/IOBufferMemoryDescriptor.iig>
44 kIOUserClientScalarArrayCountMax = 16,
46 typedef uint64_t IOUserClientScalarArray[kIOUserClientScalarArrayCountMax];
49 kIOUserClientAsyncReferenceCountMax = 16,
51 typedef uint64_t IOUserClientAsyncReferenceArray[kIOUserClientAsyncReferenceCountMax];
54 kIOUserClientAsyncArgumentsCountMax = 16,
56 typedef uint64_t IOUserClientAsyncArgumentsArray[kIOUserClientAsyncArgumentsCountMax];
58 // CopyClientMemoryForType options
60 kIOUserClientMemoryReadOnly = 0x00000001,
65 * @abstract Constant to denote a variable length structure argument to IOUserClient.
66 * @constant kIOUserClientVariableStructureSize Use in the structures IOUserClientMethodDispatch to specify the size of the structure is variable.
69 kIOUserClientVariableStructureSize = 0xffffffff
74 #define IO_USER_CLIENT_METHOD_ARGUMENTS_CURRENT_VERSION 2
75 kIOUserClientMethodArgumentsCurrentVersion = IO_USER_CLIENT_METHOD_ARGUMENTS_CURRENT_VERSION
79 * @struct IOUserClientMethodArguments
80 * @brief Holds arguments from IOKit.framework IOConnectMethod calls.
81 * @discussion Any argument may be passed as NULL if not passed by the caller.
82 * @field selector Selector argument to IOConnectMethod.
83 * @field scalarInput Array of scalars from caller.
84 * @field scalarInputCount Count of valid scalars in scalarInput.
85 * @field structureInput OSData object containing structure input from IOConnectMethod.
86 * @field structureInputDescriptor IOMemoryDescriptor containing structure input from IOConnectMethod.
87 * This parameter is only set for large structures, and if set structureInput will be NULL.
88 * @field scalarOutput Array of scalars to return to the caller.
89 * @field scalarOutputCount Count of scalars to return to the caller in scalarOutput.
90 * @field structureOutput An OSData to be returned to the caller as structure output.
91 * A reference will be consumed by the caller. It is an error to set this field if
92 * structureOutputDescriptor was passed in
93 * @field structureOutputDescriptor A IOMemoryDescriptor specified by the caller for structure output.
94 * @field structureOutputMaximumSize Maximum size of structure output specified by caller
95 * or kIOUserClientVariableStructureSize.
96 * @field completion For IOConnectAsyncMethod, an OSAction used to deliver async data to the caller.
97 * It is only retained during the invocation of ExternalMethod and should be retained if
101 struct IOUserClientMethodArguments {
104 OSAction * completion;
105 const uint64_t * scalarInput;
106 uint32_t scalarInputCount;
107 OSData * structureInput;
108 IOMemoryDescriptor * structureInputDescriptor;
109 uint64_t * scalarOutput;
110 uint32_t scalarOutputCount;
111 OSData * structureOutput;
112 IOMemoryDescriptor * structureOutputDescriptor;
113 uint64_t structureOutputMaximumSize;
114 uint64_t __reserved[30];
117 typedef kern_return_t (*IOUserClientMethodFunction)(
120 IOUserClientMethodArguments * arguments);
123 * @struct IOUserClientMethodDispatch
124 * @brief Used to check fields in IOUserClientMethodArguments
125 * @field function to invoke after making the checks specified below. If NULL and all checks pass,
126 * kIOReturnNoCompletion will be returned for the caller to implement the method.
127 * @field checkCompletionExists
128 * if true completion field must be set,
129 * if false must be zero,
131 * @field checkScalarInputCount
132 * if has value kIOUserClientVariableStructureSize don't care,
133 * otherwise must equal args->scalarInputCount
134 * @field checkStructureInputSize
135 * if has value kIOUserClientVariableStructureSize don't care,
136 * otherwise must equal length of structureInput or structureInputDescriptor
137 * @field checkScalarOutputCount
138 * if has value kIOUserClientVariableStructureSize don't care,
139 * otherwise must equal args->scalarOutputCount
140 * @field checkStructureOutputSize
141 * if has value kIOUserClientVariableStructureSize don't care,
142 * otherwise must equal length of structureOutputMaximumSize
145 struct IOUserClientMethodDispatch {
146 IOUserClientMethodFunction function;
147 uint32_t checkCompletionExists;
148 uint32_t checkScalarInputCount;
149 uint32_t checkStructureInputSize;
150 uint32_t checkScalarOutputCount;
151 uint32_t checkStructureOutputSize;
155 * @class IOUserClient
158 * IOUserClient represents a connection opened by IOServiceOpen in the IOKit.framework.
161 * An application may open an IOUserClient by calling IOServiceOpen(). This results in a call
162 * to the IOService::NewUserClient API to create an instance representing the connection.
163 * and to receive untyped data via IOConnectMethod/IOConnectAsyncMethod.
164 * As an IOService subclass, IOUserClient receives the normal Start()/Stop() lifecyle calls.
168 #include <DriverKit/IOBufferMemoryDescriptor.h>
172 class KERNEL IOUserClient : public IOService
182 * @brief Receive arguments from IOKit.framework IOConnectMethod calls.
183 * @discussion IOConnectMethod calls from the owner of the connection come here.
184 * Any argument may be passed as NULL if not passed by the caller.
185 * @param selector Selector argument to IOConnectMethod.
186 * @param scalarInput Array of scalars from caller.
187 * @param scalarInputCount Count of valid scalars in scalarInput.
188 * @param structureInput OSData object containing structure input from IOConnectMethod.
189 * @param structureInputDescriptor IOMemoryDescriptor containing structure input from IOConnectMethod.
190 * This parameter is only set for large structures, and if set structureInput will be NULL.
191 * @param scalarOutput Array of scalars to return to the caller.
192 * @param scalarOutputCount Count of scalars to return to the caller in scalarOutput.
193 * @param structureOutput An OSData to be returned to the caller as structureOutput.
194 * A reference will be consumed by the caller.
195 * @param structureOutputDescriptor An IOMemoryDescriptor to be returned to the caller as structureOutput.
196 * A reference will be consumed by the caller.
197 * Only one of structureOutput and structureOutputDescriptor may set.
198 * @param completion For IOConnectAsyncMethod, an OSAction used to deliver async data to the caller.
199 * It should be passed to the AsyncCompletion() method and released.
200 * @return kIOReturnSuccess on success. See IOReturn.h for error codes.
203 virtual kern_return_t
206 IOUserClientMethodArguments * arguments,
207 const IOUserClientMethodDispatch * dispatch,
209 void * reference) LOCALONLY;
213 * @brief Send asynchronous arguments to a completion supplied by ExternalMethod().
214 * @discussion IOConnectAsyncMethod calls from the owner of the connection come will pass an OSAction instance.
215 * To deliver the asynchronous results the driver calls AsyncCompletion().
216 * @param action OSAction passed to IOExternalMethod().
217 * @param status An IOReturn status value to be sent.
218 * @param asyncData An array of scalar data to be sent.
219 * @param asyncDataCount Count of valid data in asyncData.
223 OSAction * action TARGET,
225 const IOUserClientAsyncArgumentsArray asyncData,
226 uint32_t asyncDataCount) = 0;
229 * @brief Return an IOMemoryDescriptor to be mapped into the client task.
230 * @discussion IOConnectMapMemory()/UnmapMemory() will result in a call to this method to obtain
231 * an IOMemoryDescriptor instance for shared memory. For a given IOUserClient instance, calling
232 * CopyClientMemoryForType() with a given type, should return the same IOMemoryDescriptor instance.
233 * @param type Type parameter IOConnectMapMemory()/UnmapMemory().
234 * @param options Set kIOUserClientMemoryReadOnly for memory to be mapped read only in the client.
235 * @param memory An instance of IOMemoryDescriptor on success. One reference will be consumed by the caller
237 * @return kIOReturnSuccess on success. See IOReturn.h for error codes.
239 virtual kern_return_t
240 CopyClientMemoryForType(
243 IOMemoryDescriptor ** memory) = 0;
246 * @brief Create a memory descriptor that describes a set of virtual ranges in
247 * the client task of the user client.
248 * @param memoryDescriptorCreateOptions
249 * kIOMemoryDirectionIn memory described will be writable
250 * kIOMemoryDirectionOut memory described will be readable
251 * @param segmentsCount Number of valid address ranges being passed
252 * in the segments array.
253 * @param segments Array of address ranges.
254 * @param memory Returned IOMemoryDescriptor object with +1 retain count.
255 * @return kIOReturnSuccess on success. See IOReturn.h for error codes.
257 virtual kern_return_t
258 CreateMemoryDescriptorFromClient(
259 uint64_t memoryDescriptorCreateOptions,
260 uint32_t segmentsCount,
261 const IOAddressSegment segments[32],
262 IOMemoryDescriptor ** memory) __attribute__((availability(driverkit,introduced=20.0)));
265 virtual kern_return_t
268 const IOUserClientScalarArray scalarInput,
269 uint32_t scalarInputCount,
270 OSData * structureInput,
271 IOMemoryDescriptor * structureInputDescriptor,
272 IOUserClientScalarArray scalarOutput,
273 uint32_t * scalarOutputCount,
274 uint64_t structureOutputMaximumSize,
275 OSData ** structureOutput,
276 IOMemoryDescriptor * structureOutputDescriptor,
277 OSAction * completion TYPE(IOUserClient::AsyncCompletion)) LOCAL;
281 OSAction * action TARGET,
283 const IOUserClientAsyncArgumentsArray asyncData,
284 uint32_t asyncDataCount)
286 TYPE(IOUserClient::AsyncCompletion);
289 #endif /* ! _IOKIT_UIOUSERCLIENT_H */