1c1dac77fSApple OSS Distributions /*
2a5e72196SApple OSS Distributions * Copyright (c) 1998-2019 Apple Inc. All rights reserved.
3c1dac77fSApple OSS Distributions *
4e13b1fa5SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5c1dac77fSApple OSS Distributions *
6e13b1fa5SApple OSS Distributions * This file contains Original Code and/or Modifications of Original Code
7e13b1fa5SApple OSS Distributions * as defined in and that are subject to the Apple Public Source License
8e13b1fa5SApple OSS Distributions * Version 2.0 (the 'License'). You may not use this file except in
9e13b1fa5SApple OSS Distributions * compliance with the License. The rights granted to you under the License
10e13b1fa5SApple OSS Distributions * may not be used to create, or enable the creation or redistribution of,
11e13b1fa5SApple OSS Distributions * unlawful or unlicensed copies of an Apple operating system, or to
12e13b1fa5SApple OSS Distributions * circumvent, violate, or enable the circumvention or violation of, any
13e13b1fa5SApple OSS Distributions * terms of an Apple operating system software license agreement.
14c1dac77fSApple OSS Distributions *
15e13b1fa5SApple OSS Distributions * Please obtain a copy of the License at
16e13b1fa5SApple OSS Distributions * http://www.opensource.apple.com/apsl/ and read it before using this file.
17e13b1fa5SApple OSS Distributions *
18e13b1fa5SApple OSS Distributions * The Original Code and all software distributed under the License are
19e13b1fa5SApple OSS Distributions * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20c1dac77fSApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21c1dac77fSApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22e13b1fa5SApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23e13b1fa5SApple OSS Distributions * Please see the License for the specific language governing rights and
24e13b1fa5SApple OSS Distributions * limitations under the License.
25c1dac77fSApple OSS Distributions *
26e13b1fa5SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27c1dac77fSApple OSS Distributions */
28368ad365SApple OSS Distributions
293ca3bd55SApple OSS Distributions #include <libkern/c++/OSKext.h>
30bb611c8fSApple OSS Distributions #include <libkern/c++/OSSharedPtr.h>
31c1dac77fSApple OSS Distributions #include <IOKit/IOKitServer.h>
32e13b1fa5SApple OSS Distributions #include <IOKit/IOKitKeysPrivate.h>
33c1dac77fSApple OSS Distributions #include <IOKit/IOUserClient.h>
34c1dac77fSApple OSS Distributions #include <IOKit/IOService.h>
35c1dac77fSApple OSS Distributions #include <IOKit/IORegistryEntry.h>
36c1dac77fSApple OSS Distributions #include <IOKit/IOCatalogue.h>
37c1dac77fSApple OSS Distributions #include <IOKit/IOMemoryDescriptor.h>
383ca3bd55SApple OSS Distributions #include <IOKit/IOBufferMemoryDescriptor.h>
39c1dac77fSApple OSS Distributions #include <IOKit/IOLib.h>
4076e12aa3SApple OSS Distributions #include <IOKit/IOBSD.h>
41855239e5SApple OSS Distributions #include <IOKit/IOStatisticsPrivate.h>
42855239e5SApple OSS Distributions #include <IOKit/IOTimeStamp.h>
43cc9a6355SApple OSS Distributions #include <IOKit/IODeviceTreeSupport.h>
44a5e72196SApple OSS Distributions #include <IOKit/IOUserServer.h>
45186b8fceSApple OSS Distributions #include <IOKit/system.h>
463ca3bd55SApple OSS Distributions #include <libkern/OSDebug.h>
47a5e72196SApple OSS Distributions #include <DriverKit/OSAction.h>
48e13b1fa5SApple OSS Distributions #include <sys/proc.h>
49855239e5SApple OSS Distributions #include <sys/kauth.h>
50a3bb9fccSApple OSS Distributions #include <sys/codesign.h>
51aca3beaaSApple OSS Distributions #include <sys/code_signing.h>
52*8d741a5dSApple OSS Distributions #include <vm/vm_kern_xnu.h>
53855239e5SApple OSS Distributions
5488cc0b97SApple OSS Distributions #include <mach/sdt.h>
55a5e72196SApple OSS Distributions #include <os/hash.h>
5688cc0b97SApple OSS Distributions
57e6231be0SApple OSS Distributions #include <libkern/amfi/amfi.h>
58e6231be0SApple OSS Distributions
59855239e5SApple OSS Distributions #if CONFIG_MACF
60855239e5SApple OSS Distributions
61855239e5SApple OSS Distributions extern "C" {
62855239e5SApple OSS Distributions #include <security/mac_framework.h>
63855239e5SApple OSS Distributions };
64855239e5SApple OSS Distributions #include <sys/kauth.h>
65855239e5SApple OSS Distributions
66855239e5SApple OSS Distributions #define IOMACF_LOG 0
67855239e5SApple OSS Distributions
68855239e5SApple OSS Distributions #endif /* CONFIG_MACF */
69c1dac77fSApple OSS Distributions
70c1dac77fSApple OSS Distributions #include <IOKit/assert.h>
71c1dac77fSApple OSS Distributions
72368ad365SApple OSS Distributions #include "IOServicePrivate.h"
73e13b1fa5SApple OSS Distributions #include "IOKitKernelInternal.h"
74e13b1fa5SApple OSS Distributions
75e13b1fa5SApple OSS Distributions #define SCALAR64(x) ((io_user_scalar_t)((unsigned int)x))
76e13b1fa5SApple OSS Distributions #define SCALAR32(x) ((uint32_t )x)
77186b8fceSApple OSS Distributions #define ARG32(x) ((void *)(uintptr_t)SCALAR32(x))
783ca3bd55SApple OSS Distributions #define REF64(x) ((io_user_reference_t)((UInt64)(x)))
79e13b1fa5SApple OSS Distributions #define REF32(x) ((int)(x))
80e13b1fa5SApple OSS Distributions
81a5e72196SApple OSS Distributions enum{
82e13b1fa5SApple OSS Distributions kIOUCAsync0Flags = 3ULL,
8388cc0b97SApple OSS Distributions kIOUCAsync64Flag = 1ULL,
8488cc0b97SApple OSS Distributions kIOUCAsyncErrorLoggedFlag = 2ULL
85e13b1fa5SApple OSS Distributions };
86368ad365SApple OSS Distributions
87855239e5SApple OSS Distributions #if IOKITSTATS
88855239e5SApple OSS Distributions
89855239e5SApple OSS Distributions #define IOStatisticsRegisterCounter() \
90855239e5SApple OSS Distributions do { \
91855239e5SApple OSS Distributions reserved->counter = IOStatistics::registerUserClient(this); \
92855239e5SApple OSS Distributions } while (0)
93855239e5SApple OSS Distributions
94855239e5SApple OSS Distributions #define IOStatisticsUnregisterCounter() \
95855239e5SApple OSS Distributions do { \
96855239e5SApple OSS Distributions if (reserved) \
97855239e5SApple OSS Distributions IOStatistics::unregisterUserClient(reserved->counter); \
98855239e5SApple OSS Distributions } while (0)
99855239e5SApple OSS Distributions
100855239e5SApple OSS Distributions #define IOStatisticsClientCall() \
101855239e5SApple OSS Distributions do { \
102855239e5SApple OSS Distributions IOStatistics::countUserClientCall(client); \
103855239e5SApple OSS Distributions } while (0)
104855239e5SApple OSS Distributions
105855239e5SApple OSS Distributions #else
106855239e5SApple OSS Distributions
107855239e5SApple OSS Distributions #define IOStatisticsRegisterCounter()
108855239e5SApple OSS Distributions #define IOStatisticsUnregisterCounter()
109855239e5SApple OSS Distributions #define IOStatisticsClientCall()
110855239e5SApple OSS Distributions
111855239e5SApple OSS Distributions #endif /* IOKITSTATS */
112855239e5SApple OSS Distributions
11388cc0b97SApple OSS Distributions #if DEVELOPMENT || DEBUG
11488cc0b97SApple OSS Distributions
11588cc0b97SApple OSS Distributions #define FAKE_STACK_FRAME(a) \
11688cc0b97SApple OSS Distributions const void ** __frameptr; \
11788cc0b97SApple OSS Distributions const void * __retaddr; \
11888cc0b97SApple OSS Distributions __frameptr = (typeof(__frameptr)) __builtin_frame_address(0); \
11988cc0b97SApple OSS Distributions __retaddr = __frameptr[1]; \
12088cc0b97SApple OSS Distributions __frameptr[1] = (a);
12188cc0b97SApple OSS Distributions
12288cc0b97SApple OSS Distributions #define FAKE_STACK_FRAME_END() \
12388cc0b97SApple OSS Distributions __frameptr[1] = __retaddr;
12488cc0b97SApple OSS Distributions
12588cc0b97SApple OSS Distributions #else /* DEVELOPMENT || DEBUG */
12688cc0b97SApple OSS Distributions
12788cc0b97SApple OSS Distributions #define FAKE_STACK_FRAME(a)
12888cc0b97SApple OSS Distributions #define FAKE_STACK_FRAME_END()
12988cc0b97SApple OSS Distributions
13088cc0b97SApple OSS Distributions #endif /* DEVELOPMENT || DEBUG */
13188cc0b97SApple OSS Distributions
132a5e72196SApple OSS Distributions #define ASYNC_REF_COUNT (sizeof(io_async_ref_t) / sizeof(natural_t))
133a5e72196SApple OSS Distributions #define ASYNC_REF64_COUNT (sizeof(io_async_ref64_t) / sizeof(io_user_reference_t))
134a5e72196SApple OSS Distributions
135c1dac77fSApple OSS Distributions /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
136c1dac77fSApple OSS Distributions
137c1dac77fSApple OSS Distributions extern "C" {
13814e3d835SApple OSS Distributions #include <mach/mach_traps.h>
139*8d741a5dSApple OSS Distributions #include <vm/vm_map_xnu.h>
140c1dac77fSApple OSS Distributions } /* extern "C" */
141c1dac77fSApple OSS Distributions
142a5e72196SApple OSS Distributions struct IOMachPortHashList;
143a5e72196SApple OSS Distributions
144a5e72196SApple OSS Distributions static_assert(IKOT_MAX_TYPE <= 255);
145a5e72196SApple OSS Distributions
146c1dac77fSApple OSS Distributions /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
147c1dac77fSApple OSS Distributions
148c1dac77fSApple OSS Distributions // IOMachPort maps OSObjects to ports, avoiding adding an ivar to OSObject.
149c1dac77fSApple OSS Distributions class IOMachPort : public OSObject
150c1dac77fSApple OSS Distributions {
151a5e72196SApple OSS Distributions OSDeclareDefaultStructors(IOMachPort);
152c1dac77fSApple OSS Distributions public:
1531031c584SApple OSS Distributions mach_port_mscount_t mscount;
1541031c584SApple OSS Distributions IOLock lock;
155a5e72196SApple OSS Distributions SLIST_ENTRY(IOMachPort) link;
156c1dac77fSApple OSS Distributions ipc_port_t port;
1571031c584SApple OSS Distributions OSObject* XNU_PTRAUTH_SIGNED_PTR("IOMachPort.object") object;
158c1dac77fSApple OSS Distributions
159a5e72196SApple OSS Distributions static IOMachPort* withObjectAndType(OSObject *obj, ipc_kobject_type_t type);
160a5e72196SApple OSS Distributions
161a5e72196SApple OSS Distributions static IOMachPortHashList* bucketForObject(OSObject *obj,
162c1dac77fSApple OSS Distributions ipc_kobject_type_t type);
163a5e72196SApple OSS Distributions
164e6231be0SApple OSS Distributions static LIBKERN_RETURNS_NOT_RETAINED IOMachPort* portForObjectInBucket(IOMachPortHashList *bucket, OSObject *obj, ipc_kobject_type_t type);
165a5e72196SApple OSS Distributions
166fad439e7SApple OSS Distributions static bool noMoreSendersForObject( OSObject * obj,
167fad439e7SApple OSS Distributions ipc_kobject_type_t type, mach_port_mscount_t * mscount );
168c1dac77fSApple OSS Distributions static void releasePortForObject( OSObject * obj,
169c1dac77fSApple OSS Distributions ipc_kobject_type_t type );
170368ad365SApple OSS Distributions
171c1dac77fSApple OSS Distributions static mach_port_name_t makeSendRightForTask( task_t task,
172c1dac77fSApple OSS Distributions io_object_t obj, ipc_kobject_type_t type );
173c1dac77fSApple OSS Distributions
1740f3703acSApple OSS Distributions virtual void free() APPLE_KEXT_OVERRIDE;
175c1dac77fSApple OSS Distributions };
176c1dac77fSApple OSS Distributions
177c1dac77fSApple OSS Distributions #define super OSObject
178bb611c8fSApple OSS Distributions OSDefineMetaClassAndStructorsWithZone(IOMachPort, OSObject, ZC_ZFREE_CLEARMEM)
179c1dac77fSApple OSS Distributions
180c1dac77fSApple OSS Distributions static IOLock * gIOObjectPortLock;
181a5e72196SApple OSS Distributions IOLock * gIOUserServerLock;
182c1dac77fSApple OSS Distributions
183bb611c8fSApple OSS Distributions SECURITY_READ_ONLY_LATE(const struct io_filter_callbacks *) gIOUCFilterCallbacks;
184bb611c8fSApple OSS Distributions
185c1dac77fSApple OSS Distributions /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
186c1dac77fSApple OSS Distributions
187a5e72196SApple OSS Distributions SLIST_HEAD(IOMachPortHashList, IOMachPort);
188c1dac77fSApple OSS Distributions
189bb611c8fSApple OSS Distributions #if defined(XNU_TARGET_OS_OSX)
190a5e72196SApple OSS Distributions #define PORT_HASH_SIZE 4096
191bb611c8fSApple OSS Distributions #else /* defined(!XNU_TARGET_OS_OSX) */
192bb611c8fSApple OSS Distributions #define PORT_HASH_SIZE 256
193bb611c8fSApple OSS Distributions #endif /* !defined(!XNU_TARGET_OS_OSX) */
194a5e72196SApple OSS Distributions
195bb611c8fSApple OSS Distributions IOMachPortHashList gIOMachPortHash[PORT_HASH_SIZE];
196a5e72196SApple OSS Distributions
197a5e72196SApple OSS Distributions void
IOMachPortInitialize(void)198a5e72196SApple OSS Distributions IOMachPortInitialize(void)
199c1dac77fSApple OSS Distributions {
200a5e72196SApple OSS Distributions for (size_t i = 0; i < PORT_HASH_SIZE; i++) {
201bb611c8fSApple OSS Distributions SLIST_INIT(&gIOMachPortHash[i]);
202a5e72196SApple OSS Distributions }
203a5e72196SApple OSS Distributions }
204c1dac77fSApple OSS Distributions
205a5e72196SApple OSS Distributions IOMachPortHashList*
bucketForObject(OSObject * obj,ipc_kobject_type_t type)206a5e72196SApple OSS Distributions IOMachPort::bucketForObject(OSObject *obj, ipc_kobject_type_t type )
207cc9a6355SApple OSS Distributions {
208bb611c8fSApple OSS Distributions return &gIOMachPortHash[os_hash_kernel_pointer(obj) % PORT_HASH_SIZE];
209cc9a6355SApple OSS Distributions }
210c1dac77fSApple OSS Distributions
211a5e72196SApple OSS Distributions IOMachPort*
portForObjectInBucket(IOMachPortHashList * bucket,OSObject * obj,ipc_kobject_type_t type)212a5e72196SApple OSS Distributions IOMachPort::portForObjectInBucket(IOMachPortHashList *bucket, OSObject *obj, ipc_kobject_type_t type)
213c1dac77fSApple OSS Distributions {
214a5e72196SApple OSS Distributions IOMachPort *machPort;
215c1dac77fSApple OSS Distributions
216a5e72196SApple OSS Distributions SLIST_FOREACH(machPort, bucket, link) {
2171031c584SApple OSS Distributions if (machPort->object == obj && iokit_port_type(machPort->port) == type) {
218a5e72196SApple OSS Distributions return machPort;
219a5e72196SApple OSS Distributions }
220a5e72196SApple OSS Distributions }
221a5e72196SApple OSS Distributions return NULL;
222fad439e7SApple OSS Distributions }
223c1dac77fSApple OSS Distributions
224a5e72196SApple OSS Distributions IOMachPort*
withObjectAndType(OSObject * obj,ipc_kobject_type_t type)225a5e72196SApple OSS Distributions IOMachPort::withObjectAndType(OSObject *obj, ipc_kobject_type_t type)
226a5e72196SApple OSS Distributions {
227a5e72196SApple OSS Distributions IOMachPort *machPort = NULL;
228a5e72196SApple OSS Distributions
229a5e72196SApple OSS Distributions machPort = new IOMachPort;
230a5e72196SApple OSS Distributions if (__improbable(machPort && !machPort->init())) {
231e6231be0SApple OSS Distributions OSSafeReleaseNULL(machPort);
232a5e72196SApple OSS Distributions return NULL;
233c1dac77fSApple OSS Distributions }
234c1dac77fSApple OSS Distributions
235a5e72196SApple OSS Distributions machPort->object = obj;
2361031c584SApple OSS Distributions machPort->port = iokit_alloc_object_port(machPort, type);
2371031c584SApple OSS Distributions IOLockInlineInit(&machPort->lock);
238c1dac77fSApple OSS Distributions
239a5e72196SApple OSS Distributions obj->taggedRetain(OSTypeID(OSCollection));
240a5e72196SApple OSS Distributions machPort->mscount++;
241a5e72196SApple OSS Distributions
242a5e72196SApple OSS Distributions return machPort;
243c1dac77fSApple OSS Distributions }
244c1dac77fSApple OSS Distributions
245a5e72196SApple OSS Distributions bool
noMoreSendersForObject(OSObject * obj,ipc_kobject_type_t type,mach_port_mscount_t * mscount)246a5e72196SApple OSS Distributions IOMachPort::noMoreSendersForObject( OSObject * obj,
247fad439e7SApple OSS Distributions ipc_kobject_type_t type, mach_port_mscount_t * mscount )
248fad439e7SApple OSS Distributions {
249a5e72196SApple OSS Distributions IOMachPort *machPort = NULL;
25088cc0b97SApple OSS Distributions IOUserClient *uc;
251a5e72196SApple OSS Distributions OSAction *action;
252fad439e7SApple OSS Distributions bool destroyed = true;
253fad439e7SApple OSS Distributions
254a5e72196SApple OSS Distributions IOMachPortHashList *bucket = IOMachPort::bucketForObject(obj, type);
255fad439e7SApple OSS Distributions
256fad439e7SApple OSS Distributions obj->retain();
257fad439e7SApple OSS Distributions
258a5e72196SApple OSS Distributions lck_mtx_lock(gIOObjectPortLock);
259a5e72196SApple OSS Distributions
260a5e72196SApple OSS Distributions machPort = IOMachPort::portForObjectInBucket(bucket, obj, type);
261a5e72196SApple OSS Distributions
262fad439e7SApple OSS Distributions if (machPort) {
2633ca3bd55SApple OSS Distributions destroyed = (machPort->mscount <= *mscount);
264a5e72196SApple OSS Distributions if (!destroyed) {
265a5e72196SApple OSS Distributions *mscount = machPort->mscount;
266a5e72196SApple OSS Distributions lck_mtx_unlock(gIOObjectPortLock);
267a5e72196SApple OSS Distributions } else {
268a5e72196SApple OSS Distributions if ((IKOT_IOKIT_CONNECT == type) && (uc = OSDynamicCast(IOUserClient, obj))) {
26988cc0b97SApple OSS Distributions uc->noMoreSenders();
27088cc0b97SApple OSS Distributions }
271a5e72196SApple OSS Distributions SLIST_REMOVE(bucket, machPort, IOMachPort, link);
272a5e72196SApple OSS Distributions
2731031c584SApple OSS Distributions IOLockLock(&machPort->lock);
2741031c584SApple OSS Distributions iokit_remove_object_port(machPort->port, type);
2751031c584SApple OSS Distributions machPort->object = NULL;
2761031c584SApple OSS Distributions IOLockUnlock(&machPort->lock);
2771031c584SApple OSS Distributions
278a5e72196SApple OSS Distributions lck_mtx_unlock(gIOObjectPortLock);
279a5e72196SApple OSS Distributions
280e6231be0SApple OSS Distributions OS_ANALYZER_SUPPRESS("77508635") OSSafeReleaseNULL(machPort);
281e6231be0SApple OSS Distributions
282a5e72196SApple OSS Distributions obj->taggedRelease(OSTypeID(OSCollection));
28388cc0b97SApple OSS Distributions }
284a5e72196SApple OSS Distributions } else {
285a5e72196SApple OSS Distributions lck_mtx_unlock(gIOObjectPortLock);
286fad439e7SApple OSS Distributions }
287a5e72196SApple OSS Distributions
288a5e72196SApple OSS Distributions if ((IKOT_UEXT_OBJECT == type) && (action = OSDynamicCast(OSAction, obj))) {
289a5e72196SApple OSS Distributions action->Aborted();
290a5e72196SApple OSS Distributions }
291a5e72196SApple OSS Distributions
2925c2921b0SApple OSS Distributions if (IKOT_UEXT_OBJECT == type && IOUserServer::shouldLeakObjects()) {
2935c2921b0SApple OSS Distributions // Leak object
2945c2921b0SApple OSS Distributions obj->retain();
2955c2921b0SApple OSS Distributions }
2965c2921b0SApple OSS Distributions
297fad439e7SApple OSS Distributions obj->release();
298a5e72196SApple OSS Distributions
299a5e72196SApple OSS Distributions return destroyed;
300fad439e7SApple OSS Distributions }
301fad439e7SApple OSS Distributions
302a5e72196SApple OSS Distributions void
releasePortForObject(OSObject * obj,ipc_kobject_type_t type)303a5e72196SApple OSS Distributions IOMachPort::releasePortForObject( OSObject * obj,
304c1dac77fSApple OSS Distributions ipc_kobject_type_t type )
305c1dac77fSApple OSS Distributions {
306368ad365SApple OSS Distributions IOMachPort *machPort;
3071031c584SApple OSS Distributions IOService *service;
308a5e72196SApple OSS Distributions IOMachPortHashList *bucket = IOMachPort::bucketForObject(obj, type);
309c1dac77fSApple OSS Distributions
31088cc0b97SApple OSS Distributions assert(IKOT_IOKIT_CONNECT != type);
31188cc0b97SApple OSS Distributions
312a5e72196SApple OSS Distributions lck_mtx_lock(gIOObjectPortLock);
313c1dac77fSApple OSS Distributions
314a5e72196SApple OSS Distributions machPort = IOMachPort::portForObjectInBucket(bucket, obj, type);
315a5e72196SApple OSS Distributions
3161031c584SApple OSS Distributions if (machPort
3171031c584SApple OSS Distributions && (type == IKOT_IOKIT_OBJECT)
3181031c584SApple OSS Distributions && (service = OSDynamicCast(IOService, obj))
3191031c584SApple OSS Distributions && !service->machPortHoldDestroy()) {
320c1dac77fSApple OSS Distributions obj->retain();
321a5e72196SApple OSS Distributions SLIST_REMOVE(bucket, machPort, IOMachPort, link);
322a5e72196SApple OSS Distributions
3231031c584SApple OSS Distributions IOLockLock(&machPort->lock);
3241031c584SApple OSS Distributions iokit_remove_object_port(machPort->port, type);
3251031c584SApple OSS Distributions machPort->object = NULL;
3261031c584SApple OSS Distributions IOLockUnlock(&machPort->lock);
3271031c584SApple OSS Distributions
328a5e72196SApple OSS Distributions lck_mtx_unlock(gIOObjectPortLock);
329a5e72196SApple OSS Distributions
330e6231be0SApple OSS Distributions OS_ANALYZER_SUPPRESS("77508635") OSSafeReleaseNULL(machPort);
331e6231be0SApple OSS Distributions
332a5e72196SApple OSS Distributions obj->taggedRelease(OSTypeID(OSCollection));
333c1dac77fSApple OSS Distributions obj->release();
334a5e72196SApple OSS Distributions } else {
335a5e72196SApple OSS Distributions lck_mtx_unlock(gIOObjectPortLock);
336a5e72196SApple OSS Distributions }
337c1dac77fSApple OSS Distributions }
338c1dac77fSApple OSS Distributions
339a5e72196SApple OSS Distributions void
destroyUserReferences(OSObject * obj)340a5e72196SApple OSS Distributions IOUserClient::destroyUserReferences( OSObject * obj )
341a5e72196SApple OSS Distributions {
342a5e72196SApple OSS Distributions IOMachPort *machPort;
3431031c584SApple OSS Distributions bool destroyPort;
344a5e72196SApple OSS Distributions
345c1dac77fSApple OSS Distributions IOMachPort::releasePortForObject( obj, IKOT_IOKIT_OBJECT );
346368ad365SApple OSS Distributions
347368ad365SApple OSS Distributions // panther, 3160200
348368ad365SApple OSS Distributions // IOMachPort::releasePortForObject( obj, IKOT_IOKIT_CONNECT );
349368ad365SApple OSS Distributions
350368ad365SApple OSS Distributions obj->retain();
351a5e72196SApple OSS Distributions IOMachPortHashList *bucket = IOMachPort::bucketForObject(obj, IKOT_IOKIT_CONNECT);
352a5e72196SApple OSS Distributions IOMachPortHashList *mappingBucket = NULL;
353368ad365SApple OSS Distributions
354a5e72196SApple OSS Distributions lck_mtx_lock(gIOObjectPortLock);
355a5e72196SApple OSS Distributions
356a5e72196SApple OSS Distributions IOUserClient * uc = OSDynamicCast(IOUserClient, obj);
357a5e72196SApple OSS Distributions if (uc && uc->mappings) {
358a5e72196SApple OSS Distributions mappingBucket = IOMachPort::bucketForObject(uc->mappings, IKOT_IOKIT_CONNECT);
359a5e72196SApple OSS Distributions }
360a5e72196SApple OSS Distributions
361a5e72196SApple OSS Distributions machPort = IOMachPort::portForObjectInBucket(bucket, obj, IKOT_IOKIT_CONNECT);
362a5e72196SApple OSS Distributions
363a5e72196SApple OSS Distributions if (machPort == NULL) {
364a5e72196SApple OSS Distributions lck_mtx_unlock(gIOObjectPortLock);
365a5e72196SApple OSS Distributions goto end;
366a5e72196SApple OSS Distributions }
367a5e72196SApple OSS Distributions
368a5e72196SApple OSS Distributions SLIST_REMOVE(bucket, machPort, IOMachPort, link);
369a5e72196SApple OSS Distributions obj->taggedRelease(OSTypeID(OSCollection));
370a5e72196SApple OSS Distributions
3711031c584SApple OSS Distributions destroyPort = true;
372a5e72196SApple OSS Distributions if (uc) {
37388cc0b97SApple OSS Distributions uc->noMoreSenders();
374a5e72196SApple OSS Distributions if (uc->mappings) {
375a5e72196SApple OSS Distributions uc->mappings->taggedRetain(OSTypeID(OSCollection));
376a5e72196SApple OSS Distributions SLIST_INSERT_HEAD(mappingBucket, machPort, link);
3771031c584SApple OSS Distributions
3781031c584SApple OSS Distributions IOLockLock(&machPort->lock);
3791031c584SApple OSS Distributions machPort->object = uc->mappings;
3801031c584SApple OSS Distributions IOLockUnlock(&machPort->lock);
381a5e72196SApple OSS Distributions
382a5e72196SApple OSS Distributions lck_mtx_unlock(gIOObjectPortLock);
383368ad365SApple OSS Distributions
384e6231be0SApple OSS Distributions OSSafeReleaseNULL(uc->mappings);
3851031c584SApple OSS Distributions destroyPort = false;
386368ad365SApple OSS Distributions }
387c1dac77fSApple OSS Distributions }
388c1dac77fSApple OSS Distributions
3891031c584SApple OSS Distributions if (destroyPort) {
3901031c584SApple OSS Distributions IOLockLock(&machPort->lock);
3911031c584SApple OSS Distributions iokit_remove_object_port(machPort->port, IKOT_IOKIT_CONNECT);
3921031c584SApple OSS Distributions machPort->object = NULL;
3931031c584SApple OSS Distributions IOLockUnlock(&machPort->lock);
3941031c584SApple OSS Distributions
3951031c584SApple OSS Distributions lck_mtx_unlock(gIOObjectPortLock);
3961031c584SApple OSS Distributions OS_ANALYZER_SUPPRESS("77508635") OSSafeReleaseNULL(machPort);
3971031c584SApple OSS Distributions }
398a5e72196SApple OSS Distributions
399a5e72196SApple OSS Distributions end:
400e6231be0SApple OSS Distributions OSSafeReleaseNULL(obj);
401a5e72196SApple OSS Distributions }
402a5e72196SApple OSS Distributions
403a5e72196SApple OSS Distributions mach_port_name_t
makeSendRightForTask(task_t task,io_object_t obj,ipc_kobject_type_t type)404a5e72196SApple OSS Distributions IOMachPort::makeSendRightForTask( task_t task,
405c1dac77fSApple OSS Distributions io_object_t obj, ipc_kobject_type_t type )
406c1dac77fSApple OSS Distributions {
407a5e72196SApple OSS Distributions return iokit_make_send_right( task, obj, type );
408c1dac77fSApple OSS Distributions }
409c1dac77fSApple OSS Distributions
410a5e72196SApple OSS Distributions void
free(void)411a5e72196SApple OSS Distributions IOMachPort::free( void )
412c1dac77fSApple OSS Distributions {
413a5e72196SApple OSS Distributions if (port) {
4141031c584SApple OSS Distributions iokit_destroy_object_port(port, iokit_port_type(port));
415a5e72196SApple OSS Distributions }
4161031c584SApple OSS Distributions IOLockInlineDestroy(&lock);
417c1dac77fSApple OSS Distributions super::free();
418c1dac77fSApple OSS Distributions }
419c1dac77fSApple OSS Distributions
420c1dac77fSApple OSS Distributions /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
421c1dac77fSApple OSS Distributions
422bb611c8fSApple OSS Distributions static bool
IOTaskRegistryCompatibility(task_t task)423bb611c8fSApple OSS Distributions IOTaskRegistryCompatibility(task_t task)
424bb611c8fSApple OSS Distributions {
425bb611c8fSApple OSS Distributions return false;
426bb611c8fSApple OSS Distributions }
427bb611c8fSApple OSS Distributions
428bb611c8fSApple OSS Distributions static void
IOTaskRegistryCompatibilityMatching(task_t task,OSDictionary * matching)429bb611c8fSApple OSS Distributions IOTaskRegistryCompatibilityMatching(task_t task, OSDictionary * matching)
430bb611c8fSApple OSS Distributions {
431e6231be0SApple OSS Distributions matching->setObject(gIOServiceNotificationUserKey, kOSBooleanTrue);
432bb611c8fSApple OSS Distributions if (!IOTaskRegistryCompatibility(task)) {
433bb611c8fSApple OSS Distributions return;
434bb611c8fSApple OSS Distributions }
435bb611c8fSApple OSS Distributions matching->setObject(gIOCompatibilityMatchKey, kOSBooleanTrue);
436bb611c8fSApple OSS Distributions }
437bb611c8fSApple OSS Distributions
438bb611c8fSApple OSS Distributions /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
439bb611c8fSApple OSS Distributions
OSDefineMetaClassAndStructors(IOUserIterator,OSIterator)4408dd02465SApple OSS Distributions OSDefineMetaClassAndStructors( IOUserIterator, OSIterator )
4418dd02465SApple OSS Distributions
4428dd02465SApple OSS Distributions IOUserIterator *
4438dd02465SApple OSS Distributions IOUserIterator::withIterator(OSIterator * iter)
4448dd02465SApple OSS Distributions {
4458dd02465SApple OSS Distributions IOUserIterator * me;
4468dd02465SApple OSS Distributions
447a5e72196SApple OSS Distributions if (!iter) {
448a5e72196SApple OSS Distributions return NULL;
449a5e72196SApple OSS Distributions }
4508dd02465SApple OSS Distributions
4518dd02465SApple OSS Distributions me = new IOUserIterator;
452a5e72196SApple OSS Distributions if (me && !me->init()) {
4538dd02465SApple OSS Distributions me->release();
454a5e72196SApple OSS Distributions me = NULL;
4558dd02465SApple OSS Distributions }
456a5e72196SApple OSS Distributions if (!me) {
457e6231be0SApple OSS Distributions iter->release();
458a5e72196SApple OSS Distributions return me;
459a5e72196SApple OSS Distributions }
4608dd02465SApple OSS Distributions me->userIteratorObject = iter;
4618dd02465SApple OSS Distributions
462a5e72196SApple OSS Distributions return me;
4638dd02465SApple OSS Distributions }
4648dd02465SApple OSS Distributions
4658dd02465SApple OSS Distributions bool
init(void)4668dd02465SApple OSS Distributions IOUserIterator::init( void )
4678dd02465SApple OSS Distributions {
468a5e72196SApple OSS Distributions if (!OSObject::init()) {
469a5e72196SApple OSS Distributions return false;
470a5e72196SApple OSS Distributions }
4718dd02465SApple OSS Distributions
472aca3beaaSApple OSS Distributions IOLockInlineInit(&lock);
473a5e72196SApple OSS Distributions return true;
4748dd02465SApple OSS Distributions }
4758dd02465SApple OSS Distributions
4768dd02465SApple OSS Distributions void
free()4778dd02465SApple OSS Distributions IOUserIterator::free()
4788dd02465SApple OSS Distributions {
479a5e72196SApple OSS Distributions if (userIteratorObject) {
480a5e72196SApple OSS Distributions userIteratorObject->release();
481a5e72196SApple OSS Distributions }
482aca3beaaSApple OSS Distributions IOLockInlineDestroy(&lock);
4838dd02465SApple OSS Distributions OSObject::free();
4848dd02465SApple OSS Distributions }
4858dd02465SApple OSS Distributions
4868dd02465SApple OSS Distributions void
reset()4878dd02465SApple OSS Distributions IOUserIterator::reset()
4888dd02465SApple OSS Distributions {
489aca3beaaSApple OSS Distributions IOLockLock(&lock);
4908dd02465SApple OSS Distributions assert(OSDynamicCast(OSIterator, userIteratorObject));
4918dd02465SApple OSS Distributions ((OSIterator *)userIteratorObject)->reset();
492aca3beaaSApple OSS Distributions IOLockUnlock(&lock);
4938dd02465SApple OSS Distributions }
4948dd02465SApple OSS Distributions
4958dd02465SApple OSS Distributions bool
isValid()4968dd02465SApple OSS Distributions IOUserIterator::isValid()
4978dd02465SApple OSS Distributions {
4988dd02465SApple OSS Distributions bool ret;
4998dd02465SApple OSS Distributions
500aca3beaaSApple OSS Distributions IOLockLock(&lock);
5018dd02465SApple OSS Distributions assert(OSDynamicCast(OSIterator, userIteratorObject));
5028dd02465SApple OSS Distributions ret = ((OSIterator *)userIteratorObject)->isValid();
503aca3beaaSApple OSS Distributions IOLockUnlock(&lock);
5048dd02465SApple OSS Distributions
505a5e72196SApple OSS Distributions return ret;
5068dd02465SApple OSS Distributions }
5078dd02465SApple OSS Distributions
5088dd02465SApple OSS Distributions OSObject *
getNextObject()5098dd02465SApple OSS Distributions IOUserIterator::getNextObject()
5108dd02465SApple OSS Distributions {
511cc9a6355SApple OSS Distributions assert(false);
512a5e72196SApple OSS Distributions return NULL;
513cc9a6355SApple OSS Distributions }
514cc9a6355SApple OSS Distributions
515cc9a6355SApple OSS Distributions OSObject *
copyNextObject()516cc9a6355SApple OSS Distributions IOUserIterator::copyNextObject()
517cc9a6355SApple OSS Distributions {
518cc9a6355SApple OSS Distributions OSObject * ret = NULL;
5198dd02465SApple OSS Distributions
520aca3beaaSApple OSS Distributions IOLockLock(&lock);
521cc9a6355SApple OSS Distributions if (userIteratorObject) {
5228dd02465SApple OSS Distributions ret = ((OSIterator *)userIteratorObject)->getNextObject();
523a5e72196SApple OSS Distributions if (ret) {
524a5e72196SApple OSS Distributions ret->retain();
525a5e72196SApple OSS Distributions }
526cc9a6355SApple OSS Distributions }
527aca3beaaSApple OSS Distributions IOLockUnlock(&lock);
5288dd02465SApple OSS Distributions
529a5e72196SApple OSS Distributions return ret;
5308dd02465SApple OSS Distributions }
5318dd02465SApple OSS Distributions
5328dd02465SApple OSS Distributions /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
533c1dac77fSApple OSS Distributions extern "C" {
534c1dac77fSApple OSS Distributions // functions called from osfmk/device/iokit_rpc.c
535c1dac77fSApple OSS Distributions
536c1dac77fSApple OSS Distributions void
iokit_port_object_description(io_object_t obj,kobject_description_t desc)537bb611c8fSApple OSS Distributions iokit_port_object_description(io_object_t obj, kobject_description_t desc)
538bb611c8fSApple OSS Distributions {
539bb611c8fSApple OSS Distributions IORegistryEntry * regEntry;
540bb611c8fSApple OSS Distributions IOUserNotification * __unused noti;
541bb611c8fSApple OSS Distributions _IOServiceNotifier * __unused serviceNoti;
542bb611c8fSApple OSS Distributions OSSerialize * __unused s;
543e6231be0SApple OSS Distributions OSDictionary * __unused matching = NULL;
544bb611c8fSApple OSS Distributions
545bb611c8fSApple OSS Distributions if ((regEntry = OSDynamicCast(IORegistryEntry, obj))) {
546bb611c8fSApple OSS Distributions snprintf(desc, KOBJECT_DESCRIPTION_LENGTH, "%s(0x%qx)", obj->getMetaClass()->getClassName(), regEntry->getRegistryEntryID());
547bb611c8fSApple OSS Distributions #if DEVELOPMENT || DEBUG
548e6231be0SApple OSS Distributions } else if ((noti = OSDynamicCast(IOUserNotification, obj))) {
549e6231be0SApple OSS Distributions // serviceNoti->matching may become NULL if the port gets a no-senders notification, so we have to lock gIOObjectPortLock
550e6231be0SApple OSS Distributions IOLockLock(gIOObjectPortLock);
551e6231be0SApple OSS Distributions serviceNoti = OSDynamicCast(_IOServiceNotifier, noti->userIteratorObject);
552e6231be0SApple OSS Distributions if (serviceNoti && (matching = serviceNoti->matching)) {
553e6231be0SApple OSS Distributions matching->retain();
554e6231be0SApple OSS Distributions }
555e6231be0SApple OSS Distributions IOLockUnlock(gIOObjectPortLock);
556e6231be0SApple OSS Distributions
557e6231be0SApple OSS Distributions if (matching) {
558bb611c8fSApple OSS Distributions s = OSSerialize::withCapacity((unsigned int) page_size);
559e6231be0SApple OSS Distributions if (s && matching->serialize(s)) {
560bb611c8fSApple OSS Distributions snprintf(desc, KOBJECT_DESCRIPTION_LENGTH, "%s(%s)", obj->getMetaClass()->getClassName(), s->text());
561bb611c8fSApple OSS Distributions }
562bb611c8fSApple OSS Distributions OSSafeReleaseNULL(s);
563e6231be0SApple OSS Distributions OSSafeReleaseNULL(matching);
564e6231be0SApple OSS Distributions }
565bb611c8fSApple OSS Distributions #endif /* DEVELOPMENT || DEBUG */
566bb611c8fSApple OSS Distributions } else {
567bb611c8fSApple OSS Distributions snprintf(desc, KOBJECT_DESCRIPTION_LENGTH, "%s", obj->getMetaClass()->getClassName());
568bb611c8fSApple OSS Distributions }
569bb611c8fSApple OSS Distributions }
570bb611c8fSApple OSS Distributions
571bb611c8fSApple OSS Distributions // FIXME: Implementation of these functions are hidden from the static analyzer.
572bb611c8fSApple OSS Distributions // As for now, the analyzer doesn't consistently support wrapper functions
573bb611c8fSApple OSS Distributions // for retain and release.
574bb611c8fSApple OSS Distributions #ifndef __clang_analyzer__
575bb611c8fSApple OSS Distributions void
iokit_add_reference(io_object_t obj,natural_t type)576bb611c8fSApple OSS Distributions iokit_add_reference( io_object_t obj, natural_t type )
577c1dac77fSApple OSS Distributions {
578a5e72196SApple OSS Distributions if (!obj) {
579a5e72196SApple OSS Distributions return;
580a5e72196SApple OSS Distributions }
581c1dac77fSApple OSS Distributions obj->retain();
582c1dac77fSApple OSS Distributions }
583c1dac77fSApple OSS Distributions
584c1dac77fSApple OSS Distributions void
iokit_remove_reference(io_object_t obj)585c1dac77fSApple OSS Distributions iokit_remove_reference( io_object_t obj )
586c1dac77fSApple OSS Distributions {
587a5e72196SApple OSS Distributions if (obj) {
588c1dac77fSApple OSS Distributions obj->release();
589c1dac77fSApple OSS Distributions }
590a5e72196SApple OSS Distributions }
591bb611c8fSApple OSS Distributions #endif // __clang_analyzer__
592c1dac77fSApple OSS Distributions
59388cc0b97SApple OSS Distributions void
iokit_remove_connect_reference(LIBKERN_CONSUMED io_object_t obj)594e6231be0SApple OSS Distributions iokit_remove_connect_reference(LIBKERN_CONSUMED io_object_t obj )
59588cc0b97SApple OSS Distributions {
596a5e72196SApple OSS Distributions if (!obj) {
597a5e72196SApple OSS Distributions return;
598a5e72196SApple OSS Distributions }
59994d3b452SApple OSS Distributions obj->release();
60094d3b452SApple OSS Distributions }
60188cc0b97SApple OSS Distributions
60294d3b452SApple OSS Distributions enum {
60394d3b452SApple OSS Distributions kIPCLockNone = 0,
60494d3b452SApple OSS Distributions kIPCLockRead = 1,
60594d3b452SApple OSS Distributions kIPCLockWrite = 2
60694d3b452SApple OSS Distributions };
60794d3b452SApple OSS Distributions
60894d3b452SApple OSS Distributions void
ipcEnter(int locking)60994d3b452SApple OSS Distributions IOUserClient::ipcEnter(int locking)
61094d3b452SApple OSS Distributions {
61194d3b452SApple OSS Distributions switch (locking) {
61294d3b452SApple OSS Distributions case kIPCLockWrite:
61394d3b452SApple OSS Distributions IORWLockWrite(&lock);
61494d3b452SApple OSS Distributions break;
61594d3b452SApple OSS Distributions case kIPCLockRead:
61694d3b452SApple OSS Distributions IORWLockRead(&lock);
61794d3b452SApple OSS Distributions break;
61894d3b452SApple OSS Distributions case kIPCLockNone:
61994d3b452SApple OSS Distributions break;
62094d3b452SApple OSS Distributions default:
62194d3b452SApple OSS Distributions panic("ipcEnter");
62294d3b452SApple OSS Distributions }
62394d3b452SApple OSS Distributions
62494d3b452SApple OSS Distributions OSIncrementAtomic(&__ipc);
62594d3b452SApple OSS Distributions }
62694d3b452SApple OSS Distributions
62794d3b452SApple OSS Distributions void
ipcExit(int locking)62894d3b452SApple OSS Distributions IOUserClient::ipcExit(int locking)
62994d3b452SApple OSS Distributions {
63094d3b452SApple OSS Distributions bool finalize = false;
63194d3b452SApple OSS Distributions
63294d3b452SApple OSS Distributions assert(__ipc);
63394d3b452SApple OSS Distributions if (1 == OSDecrementAtomic(&__ipc) && isInactive()) {
63488cc0b97SApple OSS Distributions IOLockLock(gIOObjectPortLock);
63594d3b452SApple OSS Distributions if ((finalize = __ipcFinal)) {
63694d3b452SApple OSS Distributions __ipcFinal = false;
637a5e72196SApple OSS Distributions }
63888cc0b97SApple OSS Distributions IOLockUnlock(gIOObjectPortLock);
639a5e72196SApple OSS Distributions if (finalize) {
64094d3b452SApple OSS Distributions scheduleFinalize(true);
641a5e72196SApple OSS Distributions }
64288cc0b97SApple OSS Distributions }
64394d3b452SApple OSS Distributions switch (locking) {
64494d3b452SApple OSS Distributions case kIPCLockWrite:
64594d3b452SApple OSS Distributions case kIPCLockRead:
64694d3b452SApple OSS Distributions IORWLockUnlock(&lock);
64794d3b452SApple OSS Distributions break;
64894d3b452SApple OSS Distributions case kIPCLockNone:
64994d3b452SApple OSS Distributions break;
65094d3b452SApple OSS Distributions default:
65194d3b452SApple OSS Distributions panic("ipcExit");
65294d3b452SApple OSS Distributions }
65388cc0b97SApple OSS Distributions }
65488cc0b97SApple OSS Distributions
6551031c584SApple OSS Distributions void
iokit_kobject_retain(io_kobject_t machPort)6561031c584SApple OSS Distributions iokit_kobject_retain(io_kobject_t machPort)
6571031c584SApple OSS Distributions {
6581031c584SApple OSS Distributions assert(OSDynamicCast(IOMachPort, machPort));
6591031c584SApple OSS Distributions machPort->retain();
6601031c584SApple OSS Distributions }
6611031c584SApple OSS Distributions
6621031c584SApple OSS Distributions io_object_t
iokit_copy_object_for_consumed_kobject(LIBKERN_CONSUMED io_kobject_t machPort,natural_t type)6631031c584SApple OSS Distributions iokit_copy_object_for_consumed_kobject(LIBKERN_CONSUMED io_kobject_t machPort, natural_t type)
6641031c584SApple OSS Distributions {
6651031c584SApple OSS Distributions io_object_t result;
6661031c584SApple OSS Distributions
6671031c584SApple OSS Distributions assert(OSDynamicCast(IOMachPort, machPort));
6681031c584SApple OSS Distributions
6691031c584SApple OSS Distributions IOLockLock(&machPort->lock);
6701031c584SApple OSS Distributions result = machPort->object;
6711031c584SApple OSS Distributions if (result) {
6721031c584SApple OSS Distributions iokit_add_reference(result, type);
6731031c584SApple OSS Distributions }
6741031c584SApple OSS Distributions IOLockUnlock(&machPort->lock);
6751031c584SApple OSS Distributions machPort->release();
6761031c584SApple OSS Distributions return result;
6771031c584SApple OSS Distributions }
6781031c584SApple OSS Distributions
67988cc0b97SApple OSS Distributions bool
finalizeUserReferences(OSObject * obj)68088cc0b97SApple OSS Distributions IOUserClient::finalizeUserReferences(OSObject * obj)
68188cc0b97SApple OSS Distributions {
68288cc0b97SApple OSS Distributions IOUserClient * uc;
68388cc0b97SApple OSS Distributions bool ok = true;
68488cc0b97SApple OSS Distributions
685a5e72196SApple OSS Distributions if ((uc = OSDynamicCast(IOUserClient, obj))) {
68688cc0b97SApple OSS Distributions IOLockLock(gIOObjectPortLock);
687a5e72196SApple OSS Distributions if ((uc->__ipcFinal = (0 != uc->__ipc))) {
688a5e72196SApple OSS Distributions ok = false;
689a5e72196SApple OSS Distributions }
69088cc0b97SApple OSS Distributions IOLockUnlock(gIOObjectPortLock);
69188cc0b97SApple OSS Distributions }
692a5e72196SApple OSS Distributions return ok;
69388cc0b97SApple OSS Distributions }
69488cc0b97SApple OSS Distributions
695c1dac77fSApple OSS Distributions ipc_port_t
iokit_port_for_object(io_object_t obj,ipc_kobject_type_t type,ipc_kobject_t * kobj)6961031c584SApple OSS Distributions iokit_port_for_object( io_object_t obj, ipc_kobject_type_t type, ipc_kobject_t * kobj )
697c1dac77fSApple OSS Distributions {
698a5e72196SApple OSS Distributions IOMachPort *machPort = NULL;
699a5e72196SApple OSS Distributions ipc_port_t port = NULL;
700c1dac77fSApple OSS Distributions
701a5e72196SApple OSS Distributions IOMachPortHashList *bucket = IOMachPort::bucketForObject(obj, type);
702fad439e7SApple OSS Distributions
703a5e72196SApple OSS Distributions lck_mtx_lock(gIOObjectPortLock);
704a5e72196SApple OSS Distributions
705a5e72196SApple OSS Distributions machPort = IOMachPort::portForObjectInBucket(bucket, obj, type);
706a5e72196SApple OSS Distributions
707a5e72196SApple OSS Distributions if (__improbable(machPort == NULL)) {
708a5e72196SApple OSS Distributions machPort = IOMachPort::withObjectAndType(obj, type);
709a5e72196SApple OSS Distributions if (__improbable(machPort == NULL)) {
710a5e72196SApple OSS Distributions goto end;
711a5e72196SApple OSS Distributions }
712a5e72196SApple OSS Distributions SLIST_INSERT_HEAD(bucket, machPort, link);
713a5e72196SApple OSS Distributions } else {
714a5e72196SApple OSS Distributions machPort->mscount++;
715a5e72196SApple OSS Distributions }
716a5e72196SApple OSS Distributions
717a5e72196SApple OSS Distributions iokit_retain_port(machPort->port);
718fad439e7SApple OSS Distributions port = machPort->port;
719fad439e7SApple OSS Distributions
720a5e72196SApple OSS Distributions end:
7211031c584SApple OSS Distributions if (kobj) {
7221031c584SApple OSS Distributions *kobj = machPort;
7231031c584SApple OSS Distributions }
724a5e72196SApple OSS Distributions lck_mtx_unlock(gIOObjectPortLock);
725fad439e7SApple OSS Distributions
726a5e72196SApple OSS Distributions return port;
727c1dac77fSApple OSS Distributions }
728c1dac77fSApple OSS Distributions
729c1dac77fSApple OSS Distributions kern_return_t
iokit_client_died(io_object_t obj,ipc_port_t,ipc_kobject_type_t type,mach_port_mscount_t * mscount)730c1dac77fSApple OSS Distributions iokit_client_died( io_object_t obj, ipc_port_t /* port */,
731fad439e7SApple OSS Distributions ipc_kobject_type_t type, mach_port_mscount_t * mscount )
732c1dac77fSApple OSS Distributions {
733c1dac77fSApple OSS Distributions IOUserClient * client;
734c1dac77fSApple OSS Distributions IOMemoryMap * map;
735368ad365SApple OSS Distributions IOUserNotification * notify;
736bb611c8fSApple OSS Distributions IOUserServerCheckInToken * token;
737c1dac77fSApple OSS Distributions
738a5e72196SApple OSS Distributions if (!IOMachPort::noMoreSendersForObject( obj, type, mscount )) {
739a5e72196SApple OSS Distributions return kIOReturnNotReady;
740a5e72196SApple OSS Distributions }
741fad439e7SApple OSS Distributions
742bb611c8fSApple OSS Distributions switch (type) {
743bb611c8fSApple OSS Distributions case IKOT_IOKIT_CONNECT:
744a5e72196SApple OSS Distributions if ((client = OSDynamicCast( IOUserClient, obj ))) {
745855239e5SApple OSS Distributions IOStatisticsClientCall();
746aca3beaaSApple OSS Distributions IORWLockWrite(&client->lock);
747c1dac77fSApple OSS Distributions client->clientDied();
748aca3beaaSApple OSS Distributions IORWLockUnlock(&client->lock);
749368ad365SApple OSS Distributions }
750bb611c8fSApple OSS Distributions break;
751bb611c8fSApple OSS Distributions case IKOT_IOKIT_OBJECT:
752a5e72196SApple OSS Distributions if ((map = OSDynamicCast( IOMemoryMap, obj ))) {
753c1dac77fSApple OSS Distributions map->taskDied();
754a5e72196SApple OSS Distributions } else if ((notify = OSDynamicCast( IOUserNotification, obj ))) {
755a5e72196SApple OSS Distributions notify->setNotification( NULL );
756a5e72196SApple OSS Distributions }
757bb611c8fSApple OSS Distributions break;
758bb611c8fSApple OSS Distributions case IKOT_IOKIT_IDENT:
759bb611c8fSApple OSS Distributions if ((token = OSDynamicCast( IOUserServerCheckInToken, obj ))) {
760e6231be0SApple OSS Distributions token->cancel();
761bb611c8fSApple OSS Distributions }
762bb611c8fSApple OSS Distributions break;
763368ad365SApple OSS Distributions }
764c1dac77fSApple OSS Distributions
765a5e72196SApple OSS Distributions return kIOReturnSuccess;
766c1dac77fSApple OSS Distributions }
767c1dac77fSApple OSS Distributions }; /* extern "C" */
768c1dac77fSApple OSS Distributions
769c1dac77fSApple OSS Distributions /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
770c1dac77fSApple OSS Distributions
771368ad365SApple OSS Distributions class IOServiceUserNotification : public IOUserNotification
772c1dac77fSApple OSS Distributions {
773a5e72196SApple OSS Distributions OSDeclareDefaultStructors(IOServiceUserNotification);
774c1dac77fSApple OSS Distributions
775aca3beaaSApple OSS Distributions struct PingMsgKdata {
776c1dac77fSApple OSS Distributions mach_msg_header_t msgHdr;
777aca3beaaSApple OSS Distributions };
778aca3beaaSApple OSS Distributions struct PingMsgUdata {
779e13b1fa5SApple OSS Distributions OSNotificationHeader64 notifyHeader;
780c1dac77fSApple OSS Distributions };
781c1dac77fSApple OSS Distributions
78214e3d835SApple OSS Distributions enum { kMaxOutstanding = 1024 };
783c1dac77fSApple OSS Distributions
784e6231be0SApple OSS Distributions ipc_port_t remotePort;
785e6231be0SApple OSS Distributions void *msgReference;
786e6231be0SApple OSS Distributions mach_msg_size_t msgReferenceSize;
787e6231be0SApple OSS Distributions natural_t msgType;
788c1dac77fSApple OSS Distributions OSArray * newSet;
789c1dac77fSApple OSS Distributions bool armed;
79088cc0b97SApple OSS Distributions bool ipcLogged;
791c1dac77fSApple OSS Distributions
792c1dac77fSApple OSS Distributions public:
793c1dac77fSApple OSS Distributions
794c1dac77fSApple OSS Distributions virtual bool init( mach_port_t port, natural_t type,
795e13b1fa5SApple OSS Distributions void * reference, vm_size_t referenceSize,
796e13b1fa5SApple OSS Distributions bool clientIs64 );
7970f3703acSApple OSS Distributions virtual void free() APPLE_KEXT_OVERRIDE;
79876e12aa3SApple OSS Distributions void invalidatePort(void);
799c1dac77fSApple OSS Distributions
800c1dac77fSApple OSS Distributions static bool _handler( void * target,
8013ca3bd55SApple OSS Distributions void * ref, IOService * newService, IONotifier * notifier );
802c1dac77fSApple OSS Distributions virtual bool handler( void * ref, IOService * newService );
803c1dac77fSApple OSS Distributions
8040f3703acSApple OSS Distributions virtual OSObject * getNextObject() APPLE_KEXT_OVERRIDE;
805cc9a6355SApple OSS Distributions virtual OSObject * copyNextObject() APPLE_KEXT_OVERRIDE;
806c1dac77fSApple OSS Distributions };
807c1dac77fSApple OSS Distributions
808c1dac77fSApple OSS Distributions class IOServiceMessageUserNotification : public IOUserNotification
809c1dac77fSApple OSS Distributions {
810a5e72196SApple OSS Distributions OSDeclareDefaultStructors(IOServiceMessageUserNotification);
811c1dac77fSApple OSS Distributions
812aca3beaaSApple OSS Distributions struct PingMsgKdata {
813368ad365SApple OSS Distributions mach_msg_header_t msgHdr;
814368ad365SApple OSS Distributions mach_msg_body_t msgBody;
815368ad365SApple OSS Distributions mach_msg_port_descriptor_t ports[1];
816aca3beaaSApple OSS Distributions };
817aca3beaaSApple OSS Distributions struct PingMsgUdata {
8183ca3bd55SApple OSS Distributions OSNotificationHeader64 notifyHeader __attribute__ ((packed));
819368ad365SApple OSS Distributions };
820368ad365SApple OSS Distributions
821e6231be0SApple OSS Distributions ipc_port_t remotePort;
822e6231be0SApple OSS Distributions void *msgReference;
823e6231be0SApple OSS Distributions mach_msg_size_t msgReferenceSize;
824e6231be0SApple OSS Distributions mach_msg_size_t msgExtraSize;
825e6231be0SApple OSS Distributions natural_t msgType;
826e13b1fa5SApple OSS Distributions uint8_t clientIs64;
827e13b1fa5SApple OSS Distributions int owningPID;
82888cc0b97SApple OSS Distributions bool ipcLogged;
829368ad365SApple OSS Distributions
830c1dac77fSApple OSS Distributions public:
831c1dac77fSApple OSS Distributions
832c1dac77fSApple OSS Distributions virtual bool init( mach_port_t port, natural_t type,
833e13b1fa5SApple OSS Distributions void * reference, vm_size_t referenceSize,
834e13b1fa5SApple OSS Distributions bool clientIs64 );
835e13b1fa5SApple OSS Distributions
8360f3703acSApple OSS Distributions virtual void free() APPLE_KEXT_OVERRIDE;
83776e12aa3SApple OSS Distributions void invalidatePort(void);
838c1dac77fSApple OSS Distributions
839c1dac77fSApple OSS Distributions static IOReturn _handler( void * target, void * ref,
840c1dac77fSApple OSS Distributions UInt32 messageType, IOService * provider,
841c1dac77fSApple OSS Distributions void * messageArgument, vm_size_t argSize );
842c1dac77fSApple OSS Distributions virtual IOReturn handler( void * ref,
843c1dac77fSApple OSS Distributions UInt32 messageType, IOService * provider,
844c1dac77fSApple OSS Distributions void * messageArgument, vm_size_t argSize );
845c1dac77fSApple OSS Distributions
8460f3703acSApple OSS Distributions virtual OSObject * getNextObject() APPLE_KEXT_OVERRIDE;
847cc9a6355SApple OSS Distributions virtual OSObject * copyNextObject() APPLE_KEXT_OVERRIDE;
848c1dac77fSApple OSS Distributions };
849c1dac77fSApple OSS Distributions
850c1dac77fSApple OSS Distributions /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
851c1dac77fSApple OSS Distributions
852c1dac77fSApple OSS Distributions #undef super
8538dd02465SApple OSS Distributions #define super IOUserIterator
854a5e72196SApple OSS Distributions OSDefineMetaClass( IOUserNotification, IOUserIterator );
855a5e72196SApple OSS Distributions OSDefineAbstractStructors( IOUserNotification, IOUserIterator );
856c1dac77fSApple OSS Distributions
857c1dac77fSApple OSS Distributions /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
858c1dac77fSApple OSS Distributions
859a5e72196SApple OSS Distributions void
free(void)860a5e72196SApple OSS Distributions IOUserNotification::free( void )
861c1dac77fSApple OSS Distributions {
862e6231be0SApple OSS Distributions #if DEVELOPMENT || DEBUG
863e6231be0SApple OSS Distributions IOLockLock( gIOObjectPortLock);
864e6231be0SApple OSS Distributions
865e6231be0SApple OSS Distributions assert(userIteratorObject == NULL);
866e6231be0SApple OSS Distributions
867e6231be0SApple OSS Distributions IOLockUnlock( gIOObjectPortLock);
868e6231be0SApple OSS Distributions #endif /* DEVELOPMENT || DEBUG */
869c1dac77fSApple OSS Distributions
870c1dac77fSApple OSS Distributions super::free();
871c1dac77fSApple OSS Distributions }
872c1dac77fSApple OSS Distributions
873c1dac77fSApple OSS Distributions
874a5e72196SApple OSS Distributions void
setNotification(IONotifier * notify)875a5e72196SApple OSS Distributions IOUserNotification::setNotification( IONotifier * notify )
876c1dac77fSApple OSS Distributions {
8778dd02465SApple OSS Distributions OSObject * previousNotify;
878c1dac77fSApple OSS Distributions
879e6231be0SApple OSS Distributions /*
880e6231be0SApple OSS Distributions * We must retain this object here before proceeding.
881e6231be0SApple OSS Distributions * Two threads may race in setNotification(). If one thread sets a new notifier while the
882e6231be0SApple OSS Distributions * other thread sets the notifier to NULL, it is possible for the second thread to call release()
883e6231be0SApple OSS Distributions * before the first thread calls retain(). Without the retain here, this thread interleaving
884e6231be0SApple OSS Distributions * would cause the object to get released and freed before it is retained by the first thread,
885e6231be0SApple OSS Distributions * which is a UaF.
886e6231be0SApple OSS Distributions */
887e6231be0SApple OSS Distributions retain();
888e6231be0SApple OSS Distributions
889368ad365SApple OSS Distributions IOLockLock( gIOObjectPortLock);
890368ad365SApple OSS Distributions
891e6231be0SApple OSS Distributions previousNotify = userIteratorObject;
892e6231be0SApple OSS Distributions userIteratorObject = notify;
893368ad365SApple OSS Distributions
894368ad365SApple OSS Distributions IOLockUnlock( gIOObjectPortLock);
895368ad365SApple OSS Distributions
896a5e72196SApple OSS Distributions if (previousNotify) {
8978dd02465SApple OSS Distributions assert(OSDynamicCast(IONotifier, previousNotify));
8988dd02465SApple OSS Distributions ((IONotifier *)previousNotify)->remove();
899e6231be0SApple OSS Distributions
900e6231be0SApple OSS Distributions if (notify == NULL) {
901e6231be0SApple OSS Distributions release();
9028dd02465SApple OSS Distributions }
903e6231be0SApple OSS Distributions } else if (notify) {
904e6231be0SApple OSS Distributions // new IONotifier, retain the object. release() will happen in setNotification(NULL)
905e6231be0SApple OSS Distributions retain();
906e6231be0SApple OSS Distributions }
907e6231be0SApple OSS Distributions
908e6231be0SApple OSS Distributions release(); // paired with retain() at beginning of this method
909c1dac77fSApple OSS Distributions }
910c1dac77fSApple OSS Distributions
911a5e72196SApple OSS Distributions void
reset()912a5e72196SApple OSS Distributions IOUserNotification::reset()
913c1dac77fSApple OSS Distributions {
914c1dac77fSApple OSS Distributions // ?
915c1dac77fSApple OSS Distributions }
916c1dac77fSApple OSS Distributions
917a5e72196SApple OSS Distributions bool
isValid()918a5e72196SApple OSS Distributions IOUserNotification::isValid()
919c1dac77fSApple OSS Distributions {
920a5e72196SApple OSS Distributions return true;
921c1dac77fSApple OSS Distributions }
922c1dac77fSApple OSS Distributions
923c1dac77fSApple OSS Distributions /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
924c1dac77fSApple OSS Distributions
925c1dac77fSApple OSS Distributions #undef super
926c1dac77fSApple OSS Distributions #define super IOUserNotification
OSDefineMetaClassAndStructors(IOServiceUserNotification,IOUserNotification)927c1dac77fSApple OSS Distributions OSDefineMetaClassAndStructors(IOServiceUserNotification, IOUserNotification)
928c1dac77fSApple OSS Distributions
929c1dac77fSApple OSS Distributions /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
930c1dac77fSApple OSS Distributions
931a5e72196SApple OSS Distributions bool
932a5e72196SApple OSS Distributions IOServiceUserNotification::init( mach_port_t port, natural_t type,
933e13b1fa5SApple OSS Distributions void * reference, vm_size_t referenceSize,
934e13b1fa5SApple OSS Distributions bool clientIs64 )
935c1dac77fSApple OSS Distributions {
936a5e72196SApple OSS Distributions if (!super::init()) {
937a5e72196SApple OSS Distributions return false;
938a5e72196SApple OSS Distributions }
939d0c1fef6SApple OSS Distributions
940c1dac77fSApple OSS Distributions newSet = OSArray::withCapacity( 1 );
941a5e72196SApple OSS Distributions if (!newSet) {
942a5e72196SApple OSS Distributions return false;
943a5e72196SApple OSS Distributions }
944c1dac77fSApple OSS Distributions
945a5e72196SApple OSS Distributions if (referenceSize > sizeof(OSAsyncReference64)) {
946a5e72196SApple OSS Distributions return false;
947a5e72196SApple OSS Distributions }
948e13b1fa5SApple OSS Distributions
949e6231be0SApple OSS Distributions msgReferenceSize = mach_round_msg((mach_msg_size_t)referenceSize);
950e6231be0SApple OSS Distributions msgReference = IOMallocZeroData(msgReferenceSize);
951e6231be0SApple OSS Distributions if (!msgReference) {
952a5e72196SApple OSS Distributions return false;
953a5e72196SApple OSS Distributions }
954368ad365SApple OSS Distributions
955e6231be0SApple OSS Distributions remotePort = port;
956e6231be0SApple OSS Distributions msgType = type;
957e6231be0SApple OSS Distributions bcopy( reference, msgReference, referenceSize );
958368ad365SApple OSS Distributions
959a5e72196SApple OSS Distributions return true;
960c1dac77fSApple OSS Distributions }
961c1dac77fSApple OSS Distributions
962a5e72196SApple OSS Distributions void
invalidatePort(void)963a5e72196SApple OSS Distributions IOServiceUserNotification::invalidatePort(void)
96476e12aa3SApple OSS Distributions {
965e6231be0SApple OSS Distributions remotePort = MACH_PORT_NULL;
96676e12aa3SApple OSS Distributions }
96776e12aa3SApple OSS Distributions
968a5e72196SApple OSS Distributions void
free(void)969a5e72196SApple OSS Distributions IOServiceUserNotification::free( void )
970c1dac77fSApple OSS Distributions {
971e6231be0SApple OSS Distributions if (remotePort) {
972e6231be0SApple OSS Distributions iokit_release_port_send(remotePort);
973e6231be0SApple OSS Distributions }
974e6231be0SApple OSS Distributions IOFreeData(msgReference, msgReferenceSize);
975e6231be0SApple OSS Distributions OSSafeReleaseNULL(newSet);
976c1dac77fSApple OSS Distributions
977c1dac77fSApple OSS Distributions super::free();
978c1dac77fSApple OSS Distributions }
979c1dac77fSApple OSS Distributions
980a5e72196SApple OSS Distributions bool
_handler(void * target,void * ref,IOService * newService,IONotifier * notifier)981a5e72196SApple OSS Distributions IOServiceUserNotification::_handler( void * target,
982a5e72196SApple OSS Distributions void * ref, IOService * newService, IONotifier * notifier )
983a5e72196SApple OSS Distributions {
984e6231be0SApple OSS Distributions IOServiceUserNotification * targetObj = (IOServiceUserNotification *)target;
985e6231be0SApple OSS Distributions bool ret;
986e6231be0SApple OSS Distributions
987e6231be0SApple OSS Distributions targetObj->retain();
988e6231be0SApple OSS Distributions ret = targetObj->handler( ref, newService );
989e6231be0SApple OSS Distributions targetObj->release();
990e6231be0SApple OSS Distributions return ret;
991a5e72196SApple OSS Distributions }
992a5e72196SApple OSS Distributions
993a5e72196SApple OSS Distributions bool
handler(void * ref,IOService * newService)994a5e72196SApple OSS Distributions IOServiceUserNotification::handler( void * ref,
995c1dac77fSApple OSS Distributions IOService * newService )
996c1dac77fSApple OSS Distributions {
997c1dac77fSApple OSS Distributions unsigned int count;
998c1dac77fSApple OSS Distributions kern_return_t kr;
999fad439e7SApple OSS Distributions ipc_port_t port = NULL;
1000c1dac77fSApple OSS Distributions bool sendPing = false;
1001aca3beaaSApple OSS Distributions mach_msg_size_t msgSize, payloadSize;
1002c1dac77fSApple OSS Distributions
1003aca3beaaSApple OSS Distributions IOTakeLock( &lock );
1004c1dac77fSApple OSS Distributions
1005c1dac77fSApple OSS Distributions count = newSet->getCount();
1006c1dac77fSApple OSS Distributions if (count < kMaxOutstanding) {
1007c1dac77fSApple OSS Distributions newSet->setObject( newService );
1008a5e72196SApple OSS Distributions if ((sendPing = (armed && (0 == count)))) {
1009c1dac77fSApple OSS Distributions armed = false;
1010c1dac77fSApple OSS Distributions }
1011a5e72196SApple OSS Distributions }
1012c1dac77fSApple OSS Distributions
1013aca3beaaSApple OSS Distributions IOUnlock( &lock );
1014c1dac77fSApple OSS Distributions
1015e6231be0SApple OSS Distributions if (kIOServiceTerminatedNotificationType == msgType) {
10161031c584SApple OSS Distributions lck_mtx_lock(gIOObjectPortLock);
10171031c584SApple OSS Distributions newService->setMachPortHoldDestroy(true);
10181031c584SApple OSS Distributions lck_mtx_unlock(gIOObjectPortLock);
1019a5e72196SApple OSS Distributions }
1020368ad365SApple OSS Distributions
1021c1dac77fSApple OSS Distributions if (sendPing) {
10221031c584SApple OSS Distributions port = iokit_port_for_object( this, IKOT_IOKIT_OBJECT, NULL );
1023c1dac77fSApple OSS Distributions
1024aca3beaaSApple OSS Distributions payloadSize = sizeof(PingMsgUdata) - sizeof(OSAsyncReference64) + msgReferenceSize;
1025aca3beaaSApple OSS Distributions msgSize = (mach_msg_size_t)(sizeof(PingMsgKdata) + payloadSize);
1026aca3beaaSApple OSS Distributions
1027aca3beaaSApple OSS Distributions kr = kernel_mach_msg_send_with_builder_internal(0, payloadSize,
1028*8d741a5dSApple OSS Distributions MACH_SEND_KERNEL_IMPORTANCE, MACH_MSG_TIMEOUT_NONE, NULL,
1029aca3beaaSApple OSS Distributions ^(mach_msg_header_t *hdr, __assert_only mach_msg_descriptor_t *descs, void *payload){
1030aca3beaaSApple OSS Distributions PingMsgUdata *udata = (PingMsgUdata *)payload;
1031e6231be0SApple OSS Distributions
1032aca3beaaSApple OSS Distributions hdr->msgh_remote_port = remotePort;
1033aca3beaaSApple OSS Distributions hdr->msgh_local_port = port;
1034aca3beaaSApple OSS Distributions hdr->msgh_bits = MACH_MSGH_BITS(
1035e6231be0SApple OSS Distributions MACH_MSG_TYPE_COPY_SEND /*remote*/,
1036e6231be0SApple OSS Distributions MACH_MSG_TYPE_MAKE_SEND /*local*/);
1037aca3beaaSApple OSS Distributions hdr->msgh_size = msgSize;
1038aca3beaaSApple OSS Distributions hdr->msgh_id = kOSNotificationMessageID;
1039e6231be0SApple OSS Distributions
1040aca3beaaSApple OSS Distributions assert(descs == NULL);
1041aca3beaaSApple OSS Distributions /* End of kernel processed data */
1042e6231be0SApple OSS Distributions
1043aca3beaaSApple OSS Distributions udata->notifyHeader.size = 0;
1044aca3beaaSApple OSS Distributions udata->notifyHeader.type = msgType;
1045aca3beaaSApple OSS Distributions
1046aca3beaaSApple OSS Distributions assert((char *)udata->notifyHeader.reference + msgReferenceSize <= (char *)payload + payloadSize);
1047aca3beaaSApple OSS Distributions bcopy( msgReference, udata->notifyHeader.reference, msgReferenceSize );
1048e6231be0SApple OSS Distributions });
1049e6231be0SApple OSS Distributions
1050a5e72196SApple OSS Distributions if (port) {
1051fad439e7SApple OSS Distributions iokit_release_port( port );
1052a5e72196SApple OSS Distributions }
1053fad439e7SApple OSS Distributions
1054a5e72196SApple OSS Distributions if ((KERN_SUCCESS != kr) && !ipcLogged) {
105588cc0b97SApple OSS Distributions ipcLogged = true;
1056e6231be0SApple OSS Distributions IOLog("%s: kernel_mach_msg_send (0x%x)\n", __PRETTY_FUNCTION__, kr );
105788cc0b97SApple OSS Distributions }
1058c1dac77fSApple OSS Distributions }
1059c1dac77fSApple OSS Distributions
1060a5e72196SApple OSS Distributions return true;
1061c1dac77fSApple OSS Distributions }
1062a5e72196SApple OSS Distributions OSObject *
getNextObject()1063a5e72196SApple OSS Distributions IOServiceUserNotification::getNextObject()
1064c1dac77fSApple OSS Distributions {
1065cc9a6355SApple OSS Distributions assert(false);
1066a5e72196SApple OSS Distributions return NULL;
1067cc9a6355SApple OSS Distributions }
1068cc9a6355SApple OSS Distributions
1069a5e72196SApple OSS Distributions OSObject *
copyNextObject()1070a5e72196SApple OSS Distributions IOServiceUserNotification::copyNextObject()
1071cc9a6355SApple OSS Distributions {
1072c1dac77fSApple OSS Distributions unsigned int count;
1073c1dac77fSApple OSS Distributions OSObject * result;
1074c1dac77fSApple OSS Distributions
1075aca3beaaSApple OSS Distributions IOLockLock(&lock);
1076c1dac77fSApple OSS Distributions
1077c1dac77fSApple OSS Distributions count = newSet->getCount();
1078c1dac77fSApple OSS Distributions if (count) {
1079c1dac77fSApple OSS Distributions result = newSet->getObject( count - 1 );
1080c1dac77fSApple OSS Distributions result->retain();
1081c1dac77fSApple OSS Distributions newSet->removeObject( count - 1);
1082c1dac77fSApple OSS Distributions } else {
1083a5e72196SApple OSS Distributions result = NULL;
1084c1dac77fSApple OSS Distributions armed = true;
1085c1dac77fSApple OSS Distributions }
1086c1dac77fSApple OSS Distributions
1087aca3beaaSApple OSS Distributions IOLockUnlock(&lock);
108888cc0b97SApple OSS Distributions
1089a5e72196SApple OSS Distributions return result;
1090c1dac77fSApple OSS Distributions }
1091c1dac77fSApple OSS Distributions
1092c1dac77fSApple OSS Distributions /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1093c1dac77fSApple OSS Distributions
OSDefineMetaClassAndStructors(IOServiceMessageUserNotification,IOUserNotification)1094c1dac77fSApple OSS Distributions OSDefineMetaClassAndStructors(IOServiceMessageUserNotification, IOUserNotification)
1095c1dac77fSApple OSS Distributions
1096c1dac77fSApple OSS Distributions /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1097c1dac77fSApple OSS Distributions
1098a5e72196SApple OSS Distributions bool
1099a5e72196SApple OSS Distributions IOServiceMessageUserNotification::init( mach_port_t port, natural_t type,
1100e6231be0SApple OSS Distributions void * reference, vm_size_t referenceSize, bool client64 )
1101c1dac77fSApple OSS Distributions {
1102a5e72196SApple OSS Distributions if (!super::init()) {
1103a5e72196SApple OSS Distributions return false;
1104a5e72196SApple OSS Distributions }
1105368ad365SApple OSS Distributions
1106a5e72196SApple OSS Distributions if (referenceSize > sizeof(OSAsyncReference64)) {
1107a5e72196SApple OSS Distributions return false;
1108a5e72196SApple OSS Distributions }
1109e13b1fa5SApple OSS Distributions
1110e13b1fa5SApple OSS Distributions clientIs64 = client64;
1111e13b1fa5SApple OSS Distributions
1112e13b1fa5SApple OSS Distributions owningPID = proc_selfpid();
1113e13b1fa5SApple OSS Distributions
1114e6231be0SApple OSS Distributions msgReferenceSize = mach_round_msg((mach_msg_size_t)referenceSize);
1115e6231be0SApple OSS Distributions msgReference = IOMallocZeroData(msgReferenceSize);
1116e6231be0SApple OSS Distributions if (!msgReference) {
1117a5e72196SApple OSS Distributions return false;
1118a5e72196SApple OSS Distributions }
1119368ad365SApple OSS Distributions
1120e6231be0SApple OSS Distributions remotePort = port;
1121e6231be0SApple OSS Distributions msgType = type;
1122e6231be0SApple OSS Distributions bcopy( reference, msgReference, referenceSize );
1123368ad365SApple OSS Distributions
1124a5e72196SApple OSS Distributions return true;
1125c1dac77fSApple OSS Distributions }
1126c1dac77fSApple OSS Distributions
1127a5e72196SApple OSS Distributions void
invalidatePort(void)1128a5e72196SApple OSS Distributions IOServiceMessageUserNotification::invalidatePort(void)
112976e12aa3SApple OSS Distributions {
1130e6231be0SApple OSS Distributions remotePort = MACH_PORT_NULL;
113176e12aa3SApple OSS Distributions }
113276e12aa3SApple OSS Distributions
1133a5e72196SApple OSS Distributions void
free(void)1134a5e72196SApple OSS Distributions IOServiceMessageUserNotification::free( void )
1135c1dac77fSApple OSS Distributions {
1136e6231be0SApple OSS Distributions if (remotePort) {
1137e6231be0SApple OSS Distributions iokit_release_port_send(remotePort);
1138e6231be0SApple OSS Distributions }
1139e6231be0SApple OSS Distributions IOFreeData(msgReference, msgReferenceSize);
1140368ad365SApple OSS Distributions
1141c1dac77fSApple OSS Distributions super::free();
1142d0c1fef6SApple OSS Distributions }
1143c1dac77fSApple OSS Distributions
1144a5e72196SApple OSS Distributions IOReturn
_handler(void * target,void * ref,UInt32 messageType,IOService * provider,void * argument,vm_size_t argSize)1145a5e72196SApple OSS Distributions IOServiceMessageUserNotification::_handler( void * target, void * ref,
1146c1dac77fSApple OSS Distributions UInt32 messageType, IOService * provider,
1147c1dac77fSApple OSS Distributions void * argument, vm_size_t argSize )
1148c1dac77fSApple OSS Distributions {
1149e6231be0SApple OSS Distributions IOServiceMessageUserNotification * targetObj = (IOServiceMessageUserNotification *)target;
1150e6231be0SApple OSS Distributions IOReturn ret;
1151e6231be0SApple OSS Distributions
1152e6231be0SApple OSS Distributions targetObj->retain();
1153e6231be0SApple OSS Distributions ret = targetObj->handler(
1154a5e72196SApple OSS Distributions ref, messageType, provider, argument, argSize);
1155e6231be0SApple OSS Distributions targetObj->release();
1156e6231be0SApple OSS Distributions return ret;
1157c1dac77fSApple OSS Distributions }
1158c1dac77fSApple OSS Distributions
1159a5e72196SApple OSS Distributions IOReturn
handler(void * ref,UInt32 messageType,IOService * provider,void * messageArgument,vm_size_t callerArgSize)1160a5e72196SApple OSS Distributions IOServiceMessageUserNotification::handler( void * ref,
1161c1dac77fSApple OSS Distributions UInt32 messageType, IOService * provider,
116288cc0b97SApple OSS Distributions void * messageArgument, vm_size_t callerArgSize )
1163c1dac77fSApple OSS Distributions {
1164c1dac77fSApple OSS Distributions kern_return_t kr;
116588cc0b97SApple OSS Distributions vm_size_t argSize;
1166bb611c8fSApple OSS Distributions mach_msg_size_t thisMsgSize;
1167368ad365SApple OSS Distributions ipc_port_t thisPort, providerPort;
1168e13b1fa5SApple OSS Distributions
1169a5e72196SApple OSS Distributions if (kIOMessageCopyClientID == messageType) {
1170d0c1fef6SApple OSS Distributions *((void **) messageArgument) = OSNumber::withNumber(owningPID, 32);
1171a5e72196SApple OSS Distributions return kIOReturnSuccess;
1172e13b1fa5SApple OSS Distributions }
1173c1dac77fSApple OSS Distributions
1174a5e72196SApple OSS Distributions if (callerArgSize == 0) {
1175a5e72196SApple OSS Distributions if (clientIs64) {
1176e6231be0SApple OSS Distributions argSize = sizeof(io_user_reference_t);
1177a5e72196SApple OSS Distributions } else {
1178a5e72196SApple OSS Distributions argSize = sizeof(uint32_t);
1179e13b1fa5SApple OSS Distributions }
1180a5e72196SApple OSS Distributions } else {
1181a5e72196SApple OSS Distributions if (callerArgSize > kIOUserNotifyMaxMessageSize) {
1182cc9a6355SApple OSS Distributions callerArgSize = kIOUserNotifyMaxMessageSize;
1183a5e72196SApple OSS Distributions }
118488cc0b97SApple OSS Distributions argSize = callerArgSize;
1185c1dac77fSApple OSS Distributions }
1186a3bb9fccSApple OSS Distributions
1187a3bb9fccSApple OSS Distributions // adjust message size for ipc restrictions
1188e6231be0SApple OSS Distributions natural_t type = msgType;
1189a3bb9fccSApple OSS Distributions type &= ~(kIOKitNoticationMsgSizeMask << kIOKitNoticationTypeSizeAdjShift);
1190a3bb9fccSApple OSS Distributions type |= ((argSize & kIOKitNoticationMsgSizeMask) << kIOKitNoticationTypeSizeAdjShift);
1191a3bb9fccSApple OSS Distributions argSize = (argSize + kIOKitNoticationMsgSizeMask) & ~kIOKitNoticationMsgSizeMask;
1192a3bb9fccSApple OSS Distributions
1193e6231be0SApple OSS Distributions mach_msg_size_t extraSize = kIOUserNotifyMaxMessageSize + sizeof(IOServiceInterestContent64);
1194aca3beaaSApple OSS Distributions mach_msg_size_t msgSize = (mach_msg_size_t) (sizeof(PingMsgKdata) +
1195aca3beaaSApple OSS Distributions sizeof(PingMsgUdata) - sizeof(OSAsyncReference64) + msgReferenceSize);
1196e6231be0SApple OSS Distributions
1197e6231be0SApple OSS Distributions if (os_add3_overflow(msgSize, offsetof(IOServiceInterestContent64, messageArgument), argSize, &thisMsgSize)) {
1198bb611c8fSApple OSS Distributions return kIOReturnBadArgument;
1199bb611c8fSApple OSS Distributions }
1200aca3beaaSApple OSS Distributions mach_msg_size_t payloadSize = thisMsgSize - sizeof(PingMsgKdata);
1201c1dac77fSApple OSS Distributions
12021031c584SApple OSS Distributions providerPort = iokit_port_for_object( provider, IKOT_IOKIT_OBJECT, NULL );
12031031c584SApple OSS Distributions thisPort = iokit_port_for_object( this, IKOT_IOKIT_OBJECT, NULL );
120488cc0b97SApple OSS Distributions
1205aca3beaaSApple OSS Distributions kr = kernel_mach_msg_send_with_builder_internal(1, payloadSize,
1206*8d741a5dSApple OSS Distributions MACH_SEND_KERNEL_IMPORTANCE, MACH_MSG_TIMEOUT_NONE, NULL,
1207aca3beaaSApple OSS Distributions ^(mach_msg_header_t *hdr, mach_msg_descriptor_t *descs, void *payload){
1208aca3beaaSApple OSS Distributions mach_msg_port_descriptor_t *port_desc = (mach_msg_port_descriptor_t *)descs;
1209aca3beaaSApple OSS Distributions PingMsgUdata *udata = (PingMsgUdata *)payload;
1210e6231be0SApple OSS Distributions IOServiceInterestContent64 * data;
1211aca3beaaSApple OSS Distributions mach_msg_size_t dataOffset;
1212e6231be0SApple OSS Distributions
1213aca3beaaSApple OSS Distributions hdr->msgh_remote_port = remotePort;
1214aca3beaaSApple OSS Distributions hdr->msgh_local_port = thisPort;
1215aca3beaaSApple OSS Distributions hdr->msgh_bits = MACH_MSGH_BITS_COMPLEX
1216e6231be0SApple OSS Distributions | MACH_MSGH_BITS(
1217e6231be0SApple OSS Distributions MACH_MSG_TYPE_COPY_SEND /*remote*/,
1218e6231be0SApple OSS Distributions MACH_MSG_TYPE_MAKE_SEND /*local*/);
1219aca3beaaSApple OSS Distributions hdr->msgh_size = thisMsgSize;
1220aca3beaaSApple OSS Distributions hdr->msgh_id = kOSNotificationMessageID;
1221e6231be0SApple OSS Distributions
1222aca3beaaSApple OSS Distributions /* body.msgh_descriptor_count is set automatically after the closure */
1223e6231be0SApple OSS Distributions
1224aca3beaaSApple OSS Distributions port_desc[0].name = providerPort;
1225aca3beaaSApple OSS Distributions port_desc[0].disposition = MACH_MSG_TYPE_MAKE_SEND;
1226aca3beaaSApple OSS Distributions port_desc[0].type = MACH_MSG_PORT_DESCRIPTOR;
1227aca3beaaSApple OSS Distributions /* End of kernel processed data */
1228e6231be0SApple OSS Distributions
1229aca3beaaSApple OSS Distributions udata->notifyHeader.size = extraSize;
1230aca3beaaSApple OSS Distributions udata->notifyHeader.type = type;
1231aca3beaaSApple OSS Distributions bcopy( msgReference, udata->notifyHeader.reference, msgReferenceSize );
1232e6231be0SApple OSS Distributions
1233aca3beaaSApple OSS Distributions /* data is after msgReference */
1234aca3beaaSApple OSS Distributions dataOffset = sizeof(PingMsgUdata) - sizeof(OSAsyncReference64) + msgReferenceSize;
1235aca3beaaSApple OSS Distributions data = (IOServiceInterestContent64 *) (((uint8_t *) udata) + dataOffset);
123688cc0b97SApple OSS Distributions data->messageType = messageType;
123788cc0b97SApple OSS Distributions
1238a5e72196SApple OSS Distributions if (callerArgSize == 0) {
1239aca3beaaSApple OSS Distributions assert((char *)data->messageArgument + argSize <= (char *)payload + payloadSize);
124088cc0b97SApple OSS Distributions data->messageArgument[0] = (io_user_reference_t) messageArgument;
1241a5e72196SApple OSS Distributions if (!clientIs64) {
124288cc0b97SApple OSS Distributions data->messageArgument[0] |= (data->messageArgument[0] << 32);
124388cc0b97SApple OSS Distributions }
1244a5e72196SApple OSS Distributions } else {
1245aca3beaaSApple OSS Distributions assert((char *)data->messageArgument + callerArgSize <= (char *)payload + payloadSize);
124688cc0b97SApple OSS Distributions bcopy(messageArgument, data->messageArgument, callerArgSize);
124788cc0b97SApple OSS Distributions }
1248e6231be0SApple OSS Distributions });
124988cc0b97SApple OSS Distributions
1250a5e72196SApple OSS Distributions if (thisPort) {
1251368ad365SApple OSS Distributions iokit_release_port( thisPort );
1252a5e72196SApple OSS Distributions }
1253a5e72196SApple OSS Distributions if (providerPort) {
1254368ad365SApple OSS Distributions iokit_release_port( providerPort );
1255a5e72196SApple OSS Distributions }
1256fad439e7SApple OSS Distributions
1257e6231be0SApple OSS Distributions if (kr == MACH_SEND_NO_BUFFER) {
1258e6231be0SApple OSS Distributions return kIOReturnNoMemory;
1259a5e72196SApple OSS Distributions }
126088cc0b97SApple OSS Distributions
1261a5e72196SApple OSS Distributions if ((KERN_SUCCESS != kr) && !ipcLogged) {
126288cc0b97SApple OSS Distributions ipcLogged = true;
1263e6231be0SApple OSS Distributions IOLog("%s: kernel_mach_msg_send (0x%x)\n", __PRETTY_FUNCTION__, kr );
126488cc0b97SApple OSS Distributions }
1265c1dac77fSApple OSS Distributions
1266a5e72196SApple OSS Distributions return kIOReturnSuccess;
1267c1dac77fSApple OSS Distributions }
1268c1dac77fSApple OSS Distributions
1269a5e72196SApple OSS Distributions OSObject *
getNextObject()1270a5e72196SApple OSS Distributions IOServiceMessageUserNotification::getNextObject()
1271c1dac77fSApple OSS Distributions {
1272a5e72196SApple OSS Distributions return NULL;
1273c1dac77fSApple OSS Distributions }
1274c1dac77fSApple OSS Distributions
1275a5e72196SApple OSS Distributions OSObject *
copyNextObject()1276a5e72196SApple OSS Distributions IOServiceMessageUserNotification::copyNextObject()
1277cc9a6355SApple OSS Distributions {
1278a5e72196SApple OSS Distributions return NULL;
1279cc9a6355SApple OSS Distributions }
1280cc9a6355SApple OSS Distributions
1281c1dac77fSApple OSS Distributions /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1282c1dac77fSApple OSS Distributions
1283c1dac77fSApple OSS Distributions #undef super
1284c1dac77fSApple OSS Distributions #define super IOService
1285c1dac77fSApple OSS Distributions OSDefineMetaClassAndAbstractStructors( IOUserClient, IOService )
1286c1dac77fSApple OSS Distributions
128788cc0b97SApple OSS Distributions IOLock * gIOUserClientOwnersLock;
128888cc0b97SApple OSS Distributions
1289aca3beaaSApple OSS Distributions static_assert(offsetof(IOUserClient, __opaque_end) -
1290aca3beaaSApple OSS Distributions offsetof(IOUserClient, __opaque_start) == sizeof(void *) * 9,
1291aca3beaaSApple OSS Distributions "ABI check: Opaque ivars for IOUserClient must be 9 void * big");
1292aca3beaaSApple OSS Distributions
1293a5e72196SApple OSS Distributions void
initialize(void)1294a5e72196SApple OSS Distributions IOUserClient::initialize( void )
1295c1dac77fSApple OSS Distributions {
1296c1dac77fSApple OSS Distributions gIOObjectPortLock = IOLockAlloc();
129788cc0b97SApple OSS Distributions gIOUserClientOwnersLock = IOLockAlloc();
1298a5e72196SApple OSS Distributions gIOUserServerLock = IOLockAlloc();
129988cc0b97SApple OSS Distributions assert(gIOObjectPortLock && gIOUserClientOwnersLock);
1300bb611c8fSApple OSS Distributions
1301bb611c8fSApple OSS Distributions #if IOTRACKING
1302bb611c8fSApple OSS Distributions IOTrackingQueueCollectUser(IOUserIterator::gMetaClass.getTracking());
1303bb611c8fSApple OSS Distributions IOTrackingQueueCollectUser(IOServiceMessageUserNotification::gMetaClass.getTracking());
1304bb611c8fSApple OSS Distributions IOTrackingQueueCollectUser(IOServiceUserNotification::gMetaClass.getTracking());
1305bb611c8fSApple OSS Distributions IOTrackingQueueCollectUser(IOUserClient::gMetaClass.getTracking());
1306bb611c8fSApple OSS Distributions IOTrackingQueueCollectUser(IOMachPort::gMetaClass.getTracking());
1307bb611c8fSApple OSS Distributions #endif /* IOTRACKING */
1308c1dac77fSApple OSS Distributions }
1309c1dac77fSApple OSS Distributions
1310a5e72196SApple OSS Distributions void
1311bb611c8fSApple OSS Distributions #if __LP64__
1312bb611c8fSApple OSS Distributions __attribute__((__noreturn__))
1313bb611c8fSApple OSS Distributions #endif
setAsyncReference(OSAsyncReference asyncRef,mach_port_t wakePort,void * callback,void * refcon)1314a5e72196SApple OSS Distributions IOUserClient::setAsyncReference(OSAsyncReference asyncRef,
1315c1dac77fSApple OSS Distributions mach_port_t wakePort,
1316c1dac77fSApple OSS Distributions void *callback, void *refcon)
1317c1dac77fSApple OSS Distributions {
1318bb611c8fSApple OSS Distributions #if __LP64__
1319bb611c8fSApple OSS Distributions panic("setAsyncReference not valid for 64b");
1320bb611c8fSApple OSS Distributions #else
13213ca3bd55SApple OSS Distributions asyncRef[kIOAsyncReservedIndex] = ((uintptr_t) wakePort)
1322e13b1fa5SApple OSS Distributions | (kIOUCAsync0Flags & asyncRef[kIOAsyncReservedIndex]);
13233ca3bd55SApple OSS Distributions asyncRef[kIOAsyncCalloutFuncIndex] = (uintptr_t) callback;
13243ca3bd55SApple OSS Distributions asyncRef[kIOAsyncCalloutRefconIndex] = (uintptr_t) refcon;
1325bb611c8fSApple OSS Distributions #endif
1326c1dac77fSApple OSS Distributions }
1327c1dac77fSApple OSS Distributions
1328a5e72196SApple OSS Distributions void
setAsyncReference64(OSAsyncReference64 asyncRef,mach_port_t wakePort,mach_vm_address_t callback,io_user_reference_t refcon)1329a5e72196SApple OSS Distributions IOUserClient::setAsyncReference64(OSAsyncReference64 asyncRef,
1330e13b1fa5SApple OSS Distributions mach_port_t wakePort,
1331e13b1fa5SApple OSS Distributions mach_vm_address_t callback, io_user_reference_t refcon)
1332c1dac77fSApple OSS Distributions {
1333e13b1fa5SApple OSS Distributions asyncRef[kIOAsyncReservedIndex] = ((io_user_reference_t) wakePort)
1334e13b1fa5SApple OSS Distributions | (kIOUCAsync0Flags & asyncRef[kIOAsyncReservedIndex]);
1335e13b1fa5SApple OSS Distributions asyncRef[kIOAsyncCalloutFuncIndex] = (io_user_reference_t) callback;
1336e13b1fa5SApple OSS Distributions asyncRef[kIOAsyncCalloutRefconIndex] = refcon;
1337368ad365SApple OSS Distributions }
1338e13b1fa5SApple OSS Distributions
1339a5e72196SApple OSS Distributions void
setAsyncReference64(OSAsyncReference64 asyncRef,mach_port_t wakePort,mach_vm_address_t callback,io_user_reference_t refcon,task_t task)1340a5e72196SApple OSS Distributions IOUserClient::setAsyncReference64(OSAsyncReference64 asyncRef,
1341186b8fceSApple OSS Distributions mach_port_t wakePort,
1342186b8fceSApple OSS Distributions mach_vm_address_t callback, io_user_reference_t refcon, task_t task)
1343186b8fceSApple OSS Distributions {
1344186b8fceSApple OSS Distributions setAsyncReference64(asyncRef, wakePort, callback, refcon);
1345186b8fceSApple OSS Distributions if (vm_map_is_64bit(get_task_map(task))) {
1346186b8fceSApple OSS Distributions asyncRef[kIOAsyncReservedIndex] |= kIOUCAsync64Flag;
1347186b8fceSApple OSS Distributions }
1348186b8fceSApple OSS Distributions }
1349186b8fceSApple OSS Distributions
1350a5e72196SApple OSS Distributions static OSDictionary *
CopyConsoleUser(UInt32 uid)1351a5e72196SApple OSS Distributions CopyConsoleUser(UInt32 uid)
1352368ad365SApple OSS Distributions {
1353368ad365SApple OSS Distributions OSArray * array;
1354a5e72196SApple OSS Distributions OSDictionary * user = NULL;
1355368ad365SApple OSS Distributions
1356e6231be0SApple OSS Distributions OSObject * ioProperty = IORegistryEntry::getRegistryRoot()->copyProperty(gIOConsoleUsersKey);
1357e6231be0SApple OSS Distributions if ((array = OSDynamicCast(OSArray, ioProperty))) {
1358368ad365SApple OSS Distributions for (unsigned int idx = 0;
1359368ad365SApple OSS Distributions (user = OSDynamicCast(OSDictionary, array->getObject(idx)));
1360e13b1fa5SApple OSS Distributions idx++) {
1361368ad365SApple OSS Distributions OSNumber * num;
1362e13b1fa5SApple OSS Distributions
1363368ad365SApple OSS Distributions if ((num = OSDynamicCast(OSNumber, user->getObject(gIOConsoleSessionUIDKey)))
1364e13b1fa5SApple OSS Distributions && (uid == num->unsigned32BitValue())) {
1365e13b1fa5SApple OSS Distributions user->retain();
1366368ad365SApple OSS Distributions break;
1367368ad365SApple OSS Distributions }
1368e13b1fa5SApple OSS Distributions }
1369368ad365SApple OSS Distributions }
1370e6231be0SApple OSS Distributions OSSafeReleaseNULL(ioProperty);
1371e13b1fa5SApple OSS Distributions return user;
1372e13b1fa5SApple OSS Distributions }
1373e13b1fa5SApple OSS Distributions
1374a5e72196SApple OSS Distributions static OSDictionary *
CopyUserOnConsole(void)1375a5e72196SApple OSS Distributions CopyUserOnConsole(void)
1376855239e5SApple OSS Distributions {
1377855239e5SApple OSS Distributions OSArray * array;
1378a5e72196SApple OSS Distributions OSDictionary * user = NULL;
1379855239e5SApple OSS Distributions
1380e6231be0SApple OSS Distributions OSObject * ioProperty = IORegistryEntry::getRegistryRoot()->copyProperty(gIOConsoleUsersKey);
1381e6231be0SApple OSS Distributions if ((array = OSDynamicCast(OSArray, ioProperty))) {
1382855239e5SApple OSS Distributions for (unsigned int idx = 0;
1383855239e5SApple OSS Distributions (user = OSDynamicCast(OSDictionary, array->getObject(idx)));
1384a5e72196SApple OSS Distributions idx++) {
1385a5e72196SApple OSS Distributions if (kOSBooleanTrue == user->getObject(gIOConsoleSessionOnConsoleKey)) {
1386855239e5SApple OSS Distributions user->retain();
1387855239e5SApple OSS Distributions break;
1388855239e5SApple OSS Distributions }
1389855239e5SApple OSS Distributions }
1390855239e5SApple OSS Distributions }
1391e6231be0SApple OSS Distributions OSSafeReleaseNULL(ioProperty);
1392a5e72196SApple OSS Distributions return user;
1393855239e5SApple OSS Distributions }
1394855239e5SApple OSS Distributions
1395a5e72196SApple OSS Distributions IOReturn
clientHasAuthorization(task_t task,IOService * service)1396a5e72196SApple OSS Distributions IOUserClient::clientHasAuthorization( task_t task,
1397a3bb9fccSApple OSS Distributions IOService * service )
1398a3bb9fccSApple OSS Distributions {
1399a3bb9fccSApple OSS Distributions proc_t p;
1400a3bb9fccSApple OSS Distributions
1401a3bb9fccSApple OSS Distributions p = (proc_t) get_bsdtask_info(task);
1402a5e72196SApple OSS Distributions if (p) {
1403a3bb9fccSApple OSS Distributions uint64_t authorizationID;
1404a3bb9fccSApple OSS Distributions
1405a3bb9fccSApple OSS Distributions authorizationID = proc_uniqueid(p);
1406a5e72196SApple OSS Distributions if (authorizationID) {
1407a5e72196SApple OSS Distributions if (service->getAuthorizationID() == authorizationID) {
1408a5e72196SApple OSS Distributions return kIOReturnSuccess;
1409a3bb9fccSApple OSS Distributions }
1410a3bb9fccSApple OSS Distributions }
1411a3bb9fccSApple OSS Distributions }
1412a3bb9fccSApple OSS Distributions
1413a5e72196SApple OSS Distributions return kIOReturnNotPermitted;
1414a3bb9fccSApple OSS Distributions }
1415a3bb9fccSApple OSS Distributions
1416a5e72196SApple OSS Distributions IOReturn
clientHasPrivilege(void * securityToken,const char * privilegeName)1417a5e72196SApple OSS Distributions IOUserClient::clientHasPrivilege( void * securityToken,
1418e13b1fa5SApple OSS Distributions const char * privilegeName )
1419e13b1fa5SApple OSS Distributions {
1420e13b1fa5SApple OSS Distributions kern_return_t kr;
1421e13b1fa5SApple OSS Distributions security_token_t token;
1422e13b1fa5SApple OSS Distributions mach_msg_type_number_t count;
1423e13b1fa5SApple OSS Distributions task_t task;
1424e13b1fa5SApple OSS Distributions OSDictionary * user;
1425e13b1fa5SApple OSS Distributions bool secureConsole;
1426e13b1fa5SApple OSS Distributions
1427855239e5SApple OSS Distributions
1428855239e5SApple OSS Distributions if (!strncmp(privilegeName, kIOClientPrivilegeForeground,
1429a5e72196SApple OSS Distributions sizeof(kIOClientPrivilegeForeground))) {
1430a5e72196SApple OSS Distributions if (task_is_gpu_denied(current_task())) {
1431a5e72196SApple OSS Distributions return kIOReturnNotPrivileged;
1432a5e72196SApple OSS Distributions } else {
1433a5e72196SApple OSS Distributions return kIOReturnSuccess;
1434a5e72196SApple OSS Distributions }
1435855239e5SApple OSS Distributions }
1436855239e5SApple OSS Distributions
1437855239e5SApple OSS Distributions if (!strncmp(privilegeName, kIOClientPrivilegeConsoleSession,
1438a5e72196SApple OSS Distributions sizeof(kIOClientPrivilegeConsoleSession))) {
1439855239e5SApple OSS Distributions kauth_cred_t cred;
1440855239e5SApple OSS Distributions proc_t p;
1441855239e5SApple OSS Distributions
1442855239e5SApple OSS Distributions task = (task_t) securityToken;
1443a5e72196SApple OSS Distributions if (!task) {
1444855239e5SApple OSS Distributions task = current_task();
1445a5e72196SApple OSS Distributions }
1446855239e5SApple OSS Distributions p = (proc_t) get_bsdtask_info(task);
1447855239e5SApple OSS Distributions kr = kIOReturnNotPrivileged;
1448855239e5SApple OSS Distributions
1449a5e72196SApple OSS Distributions if (p && (cred = kauth_cred_proc_ref(p))) {
1450855239e5SApple OSS Distributions user = CopyUserOnConsole();
1451a5e72196SApple OSS Distributions if (user) {
1452855239e5SApple OSS Distributions OSNumber * num;
1453855239e5SApple OSS Distributions if ((num = OSDynamicCast(OSNumber, user->getObject(gIOConsoleSessionAuditIDKey)))
1454a5e72196SApple OSS Distributions && (cred->cr_audit.as_aia_p->ai_asid == (au_asid_t) num->unsigned32BitValue())) {
1455855239e5SApple OSS Distributions kr = kIOReturnSuccess;
1456855239e5SApple OSS Distributions }
1457855239e5SApple OSS Distributions user->release();
1458855239e5SApple OSS Distributions }
1459855239e5SApple OSS Distributions kauth_cred_unref(&cred);
1460855239e5SApple OSS Distributions }
1461a5e72196SApple OSS Distributions return kr;
1462855239e5SApple OSS Distributions }
1463855239e5SApple OSS Distributions
14643ca3bd55SApple OSS Distributions if ((secureConsole = !strncmp(privilegeName, kIOClientPrivilegeSecureConsoleProcess,
1465a5e72196SApple OSS Distributions sizeof(kIOClientPrivilegeSecureConsoleProcess)))) {
1466e13b1fa5SApple OSS Distributions task = (task_t)((IOUCProcessToken *)securityToken)->token;
1467a5e72196SApple OSS Distributions } else {
1468e13b1fa5SApple OSS Distributions task = (task_t)securityToken;
1469a5e72196SApple OSS Distributions }
1470e13b1fa5SApple OSS Distributions
1471e13b1fa5SApple OSS Distributions count = TASK_SECURITY_TOKEN_COUNT;
1472e13b1fa5SApple OSS Distributions kr = task_info( task, TASK_SECURITY_TOKEN, (task_info_t) &token, &count );
1473e13b1fa5SApple OSS Distributions
1474a5e72196SApple OSS Distributions if (KERN_SUCCESS != kr) {
1475a5e72196SApple OSS Distributions } else if (!strncmp(privilegeName, kIOClientPrivilegeAdministrator,
14763ca3bd55SApple OSS Distributions sizeof(kIOClientPrivilegeAdministrator))) {
1477a5e72196SApple OSS Distributions if (0 != token.val[0]) {
1478e13b1fa5SApple OSS Distributions kr = kIOReturnNotPrivileged;
1479a5e72196SApple OSS Distributions }
14803ca3bd55SApple OSS Distributions } else if (!strncmp(privilegeName, kIOClientPrivilegeLocalUser,
14813ca3bd55SApple OSS Distributions sizeof(kIOClientPrivilegeLocalUser))) {
1482e13b1fa5SApple OSS Distributions user = CopyConsoleUser(token.val[0]);
1483a5e72196SApple OSS Distributions if (user) {
1484e13b1fa5SApple OSS Distributions user->release();
1485a5e72196SApple OSS Distributions } else {
1486e13b1fa5SApple OSS Distributions kr = kIOReturnNotPrivileged;
1487a5e72196SApple OSS Distributions }
14883ca3bd55SApple OSS Distributions } else if (secureConsole || !strncmp(privilegeName, kIOClientPrivilegeConsoleUser,
14893ca3bd55SApple OSS Distributions sizeof(kIOClientPrivilegeConsoleUser))) {
1490e13b1fa5SApple OSS Distributions user = CopyConsoleUser(token.val[0]);
1491e13b1fa5SApple OSS Distributions if (user) {
1492a5e72196SApple OSS Distributions if (user->getObject(gIOConsoleSessionOnConsoleKey) != kOSBooleanTrue) {
1493e13b1fa5SApple OSS Distributions kr = kIOReturnNotPrivileged;
1494a5e72196SApple OSS Distributions } else if (secureConsole) {
1495e13b1fa5SApple OSS Distributions OSNumber * pid = OSDynamicCast(OSNumber, user->getObject(gIOConsoleSessionSecureInputPIDKey));
1496a5e72196SApple OSS Distributions if (pid && pid->unsigned32BitValue() != ((IOUCProcessToken *)securityToken)->pid) {
1497368ad365SApple OSS Distributions kr = kIOReturnNotPrivileged;
1498368ad365SApple OSS Distributions }
1499a5e72196SApple OSS Distributions }
1500e13b1fa5SApple OSS Distributions user->release();
1501a5e72196SApple OSS Distributions } else {
1502e13b1fa5SApple OSS Distributions kr = kIOReturnNotPrivileged;
1503a5e72196SApple OSS Distributions }
1504a5e72196SApple OSS Distributions } else {
1505368ad365SApple OSS Distributions kr = kIOReturnUnsupported;
1506c1dac77fSApple OSS Distributions }
1507c1dac77fSApple OSS Distributions
1508a5e72196SApple OSS Distributions return kr;
1509a5e72196SApple OSS Distributions }
1510a5e72196SApple OSS Distributions
1511a5e72196SApple OSS Distributions OSDictionary *
copyClientEntitlements(task_t task)1512a5e72196SApple OSS Distributions IOUserClient::copyClientEntitlements(task_t task)
1513a3bb9fccSApple OSS Distributions {
1514a3bb9fccSApple OSS Distributions proc_t p = NULL;
1515a3bb9fccSApple OSS Distributions pid_t pid = 0;
1516a3bb9fccSApple OSS Distributions OSDictionary *entitlements = NULL;
1517a3bb9fccSApple OSS Distributions
1518a3bb9fccSApple OSS Distributions p = (proc_t)get_bsdtask_info(task);
1519a5e72196SApple OSS Distributions if (p == NULL) {
1520bb611c8fSApple OSS Distributions return NULL;
1521a5e72196SApple OSS Distributions }
1522a3bb9fccSApple OSS Distributions pid = proc_pid(p);
1523a3bb9fccSApple OSS Distributions
1524a5e72196SApple OSS Distributions if (cs_entitlements_dictionary_copy(p, (void **)&entitlements) == 0) {
1525a5e72196SApple OSS Distributions if (entitlements) {
1526a5e72196SApple OSS Distributions return entitlements;
1527a5e72196SApple OSS Distributions }
1528a5e72196SApple OSS Distributions }
1529a3bb9fccSApple OSS Distributions
1530e6231be0SApple OSS Distributions // If the above fails, thats it
1531bb611c8fSApple OSS Distributions return NULL;
1532a5e72196SApple OSS Distributions }
1533a5e72196SApple OSS Distributions
1534bb611c8fSApple OSS Distributions OSDictionary *
copyClientEntitlementsVnode(vnode_t vnode,off_t offset)1535bb611c8fSApple OSS Distributions IOUserClient::copyClientEntitlementsVnode(vnode_t vnode, off_t offset)
1536bb611c8fSApple OSS Distributions {
1537e6231be0SApple OSS Distributions OSDictionary *entitlements = NULL;
1538bb611c8fSApple OSS Distributions
1539e6231be0SApple OSS Distributions if (cs_entitlements_dictionary_copy_vnode(vnode, offset, (void**)&entitlements) != 0) {
1540bb611c8fSApple OSS Distributions return NULL;
1541bb611c8fSApple OSS Distributions }
1542e6231be0SApple OSS Distributions return entitlements;
1543bb611c8fSApple OSS Distributions }
1544bb611c8fSApple OSS Distributions
1545a5e72196SApple OSS Distributions OSObject *
copyClientEntitlement(task_t task,const char * entitlement)1546a5e72196SApple OSS Distributions IOUserClient::copyClientEntitlement( task_t task,
1547a5e72196SApple OSS Distributions const char * entitlement )
1548a5e72196SApple OSS Distributions {
1549aca3beaaSApple OSS Distributions void *entitlement_object = NULL;
1550a5e72196SApple OSS Distributions
1551aca3beaaSApple OSS Distributions if (task == NULL) {
1552aca3beaaSApple OSS Distributions task = current_task();
1553aca3beaaSApple OSS Distributions }
1554aca3beaaSApple OSS Distributions
1555aca3beaaSApple OSS Distributions /* Validate input arguments */
1556aca3beaaSApple OSS Distributions if (task == kernel_task || entitlement == NULL) {
1557e6231be0SApple OSS Distributions return NULL;
1558e6231be0SApple OSS Distributions }
1559aca3beaaSApple OSS Distributions proc_t proc = (proc_t)get_bsdtask_info(task);
1560aca3beaaSApple OSS Distributions
1561aca3beaaSApple OSS Distributions kern_return_t ret = amfi->OSEntitlements.copyEntitlementAsOSObjectWithProc(
1562aca3beaaSApple OSS Distributions proc,
1563aca3beaaSApple OSS Distributions entitlement,
1564aca3beaaSApple OSS Distributions &entitlement_object);
1565aca3beaaSApple OSS Distributions
1566aca3beaaSApple OSS Distributions if (ret != KERN_SUCCESS) {
1567e6231be0SApple OSS Distributions return NULL;
1568e6231be0SApple OSS Distributions }
1569aca3beaaSApple OSS Distributions assert(entitlement_object != NULL);
1570e6231be0SApple OSS Distributions
1571aca3beaaSApple OSS Distributions return (OSObject*)entitlement_object;
1572a3bb9fccSApple OSS Distributions }
1573a3bb9fccSApple OSS Distributions
1574bb611c8fSApple OSS Distributions OSObject *
copyClientEntitlementVnode(struct vnode * vnode,off_t offset,const char * entitlement)1575bb611c8fSApple OSS Distributions IOUserClient::copyClientEntitlementVnode(
1576bb611c8fSApple OSS Distributions struct vnode *vnode,
1577bb611c8fSApple OSS Distributions off_t offset,
1578bb611c8fSApple OSS Distributions const char *entitlement)
1579bb611c8fSApple OSS Distributions {
1580bb611c8fSApple OSS Distributions OSDictionary *entitlements;
1581bb611c8fSApple OSS Distributions OSObject *value;
1582bb611c8fSApple OSS Distributions
1583bb611c8fSApple OSS Distributions entitlements = copyClientEntitlementsVnode(vnode, offset);
1584bb611c8fSApple OSS Distributions if (entitlements == NULL) {
1585bb611c8fSApple OSS Distributions return NULL;
1586bb611c8fSApple OSS Distributions }
1587bb611c8fSApple OSS Distributions
1588bb611c8fSApple OSS Distributions /* Fetch the entitlement value from the dictionary. */
1589bb611c8fSApple OSS Distributions value = entitlements->getObject(entitlement);
1590bb611c8fSApple OSS Distributions if (value != NULL) {
1591bb611c8fSApple OSS Distributions value->retain();
1592bb611c8fSApple OSS Distributions }
1593bb611c8fSApple OSS Distributions
1594bb611c8fSApple OSS Distributions entitlements->release();
1595bb611c8fSApple OSS Distributions return value;
1596bb611c8fSApple OSS Distributions }
1597bb611c8fSApple OSS Distributions
1598a5e72196SApple OSS Distributions bool
init()1599a5e72196SApple OSS Distributions IOUserClient::init()
1600e13b1fa5SApple OSS Distributions {
1601a5e72196SApple OSS Distributions if (getPropertyTable() || super::init()) {
1602855239e5SApple OSS Distributions return reserve();
1603a5e72196SApple OSS Distributions }
1604855239e5SApple OSS Distributions
1605855239e5SApple OSS Distributions return false;
1606e13b1fa5SApple OSS Distributions }
1607e13b1fa5SApple OSS Distributions
1608a5e72196SApple OSS Distributions bool
init(OSDictionary * dictionary)1609a5e72196SApple OSS Distributions IOUserClient::init(OSDictionary * dictionary)
1610e13b1fa5SApple OSS Distributions {
1611a5e72196SApple OSS Distributions if (getPropertyTable() || super::init(dictionary)) {
1612855239e5SApple OSS Distributions return reserve();
1613a5e72196SApple OSS Distributions }
1614855239e5SApple OSS Distributions
1615855239e5SApple OSS Distributions return false;
1616e13b1fa5SApple OSS Distributions }
1617e13b1fa5SApple OSS Distributions
1618a5e72196SApple OSS Distributions bool
initWithTask(task_t owningTask,void * securityID,UInt32 type)1619a5e72196SApple OSS Distributions IOUserClient::initWithTask(task_t owningTask,
1620c1dac77fSApple OSS Distributions void * securityID,
1621c1dac77fSApple OSS Distributions UInt32 type )
1622c1dac77fSApple OSS Distributions {
1623a5e72196SApple OSS Distributions if (getPropertyTable() || super::init()) {
1624855239e5SApple OSS Distributions return reserve();
1625a5e72196SApple OSS Distributions }
1626855239e5SApple OSS Distributions
1627855239e5SApple OSS Distributions return false;
1628c1dac77fSApple OSS Distributions }
1629c1dac77fSApple OSS Distributions
1630a5e72196SApple OSS Distributions bool
initWithTask(task_t owningTask,void * securityID,UInt32 type,OSDictionary * properties)1631a5e72196SApple OSS Distributions IOUserClient::initWithTask(task_t owningTask,
1632c1dac77fSApple OSS Distributions void * securityID,
1633c1dac77fSApple OSS Distributions UInt32 type,
1634c1dac77fSApple OSS Distributions OSDictionary * properties )
1635c1dac77fSApple OSS Distributions {
1636c1dac77fSApple OSS Distributions bool ok;
1637c1dac77fSApple OSS Distributions
1638c1dac77fSApple OSS Distributions ok = super::init( properties );
1639c1dac77fSApple OSS Distributions ok &= initWithTask( owningTask, securityID, type );
1640c1dac77fSApple OSS Distributions
1641a5e72196SApple OSS Distributions return ok;
1642c1dac77fSApple OSS Distributions }
1643c1dac77fSApple OSS Distributions
1644a5e72196SApple OSS Distributions bool
reserve()1645a5e72196SApple OSS Distributions IOUserClient::reserve()
1646855239e5SApple OSS Distributions {
1647855239e5SApple OSS Distributions if (!reserved) {
1648e6231be0SApple OSS Distributions reserved = IOMallocType(ExpansionData);
1649855239e5SApple OSS Distributions }
1650186b8fceSApple OSS Distributions setTerminateDefer(NULL, true);
1651855239e5SApple OSS Distributions IOStatisticsRegisterCounter();
1652aca3beaaSApple OSS Distributions IORWLockInlineInit(&lock);
1653aca3beaaSApple OSS Distributions IOLockInlineInit(&filterLock);
1654855239e5SApple OSS Distributions
1655855239e5SApple OSS Distributions return true;
1656855239e5SApple OSS Distributions }
1657855239e5SApple OSS Distributions
1658a5e72196SApple OSS Distributions struct IOUserClientOwner {
165988cc0b97SApple OSS Distributions task_t task;
166088cc0b97SApple OSS Distributions queue_chain_t taskLink;
166188cc0b97SApple OSS Distributions IOUserClient * uc;
166288cc0b97SApple OSS Distributions queue_chain_t ucLink;
166388cc0b97SApple OSS Distributions };
166488cc0b97SApple OSS Distributions
166588cc0b97SApple OSS Distributions IOReturn
registerOwner(task_t task)166688cc0b97SApple OSS Distributions IOUserClient::registerOwner(task_t task)
166788cc0b97SApple OSS Distributions {
166888cc0b97SApple OSS Distributions IOUserClientOwner * owner;
166988cc0b97SApple OSS Distributions IOReturn ret;
167088cc0b97SApple OSS Distributions bool newOwner;
167188cc0b97SApple OSS Distributions
167288cc0b97SApple OSS Distributions IOLockLock(gIOUserClientOwnersLock);
167388cc0b97SApple OSS Distributions
167488cc0b97SApple OSS Distributions newOwner = true;
167588cc0b97SApple OSS Distributions ret = kIOReturnSuccess;
167688cc0b97SApple OSS Distributions
1677a5e72196SApple OSS Distributions if (!owners.next) {
1678a5e72196SApple OSS Distributions queue_init(&owners);
1679a5e72196SApple OSS Distributions } else {
168088cc0b97SApple OSS Distributions queue_iterate(&owners, owner, IOUserClientOwner *, ucLink)
168188cc0b97SApple OSS Distributions {
1682a5e72196SApple OSS Distributions if (task != owner->task) {
1683a5e72196SApple OSS Distributions continue;
1684a5e72196SApple OSS Distributions }
168588cc0b97SApple OSS Distributions newOwner = false;
168688cc0b97SApple OSS Distributions break;
168788cc0b97SApple OSS Distributions }
168888cc0b97SApple OSS Distributions }
1689a5e72196SApple OSS Distributions if (newOwner) {
1690e6231be0SApple OSS Distributions owner = IOMallocType(IOUserClientOwner);
1691e6231be0SApple OSS Distributions
169288cc0b97SApple OSS Distributions owner->task = task;
169388cc0b97SApple OSS Distributions owner->uc = this;
169488cc0b97SApple OSS Distributions queue_enter_first(&owners, owner, IOUserClientOwner *, ucLink);
169588cc0b97SApple OSS Distributions queue_enter_first(task_io_user_clients(task), owner, IOUserClientOwner *, taskLink);
1696a5e72196SApple OSS Distributions if (messageAppSuspended) {
1697a5e72196SApple OSS Distributions task_set_message_app_suspended(task, true);
1698a5e72196SApple OSS Distributions }
169988cc0b97SApple OSS Distributions }
170088cc0b97SApple OSS Distributions
170188cc0b97SApple OSS Distributions IOLockUnlock(gIOUserClientOwnersLock);
170288cc0b97SApple OSS Distributions
1703a5e72196SApple OSS Distributions return ret;
170488cc0b97SApple OSS Distributions }
170588cc0b97SApple OSS Distributions
170688cc0b97SApple OSS Distributions void
noMoreSenders(void)170788cc0b97SApple OSS Distributions IOUserClient::noMoreSenders(void)
170888cc0b97SApple OSS Distributions {
170988cc0b97SApple OSS Distributions IOUserClientOwner * owner;
1710a5e72196SApple OSS Distributions IOUserClientOwner * iter;
1711a5e72196SApple OSS Distributions queue_head_t * taskque;
1712a5e72196SApple OSS Distributions bool hasMessageAppSuspended;
171388cc0b97SApple OSS Distributions
171488cc0b97SApple OSS Distributions IOLockLock(gIOUserClientOwnersLock);
171588cc0b97SApple OSS Distributions
1716a5e72196SApple OSS Distributions if (owners.next) {
1717a5e72196SApple OSS Distributions while (!queue_empty(&owners)) {
171888cc0b97SApple OSS Distributions owner = (IOUserClientOwner *)(void *) queue_first(&owners);
1719a5e72196SApple OSS Distributions taskque = task_io_user_clients(owner->task);
1720a5e72196SApple OSS Distributions queue_remove(taskque, owner, IOUserClientOwner *, taskLink);
1721a5e72196SApple OSS Distributions hasMessageAppSuspended = false;
1722a5e72196SApple OSS Distributions queue_iterate(taskque, iter, IOUserClientOwner *, taskLink) {
1723a5e72196SApple OSS Distributions hasMessageAppSuspended = iter->uc->messageAppSuspended;
1724a5e72196SApple OSS Distributions if (hasMessageAppSuspended) {
1725a5e72196SApple OSS Distributions break;
1726a5e72196SApple OSS Distributions }
1727a5e72196SApple OSS Distributions }
1728a5e72196SApple OSS Distributions task_set_message_app_suspended(owner->task, hasMessageAppSuspended);
172988cc0b97SApple OSS Distributions queue_remove(&owners, owner, IOUserClientOwner *, ucLink);
1730e6231be0SApple OSS Distributions IOFreeType(owner, IOUserClientOwner);
173188cc0b97SApple OSS Distributions }
173288cc0b97SApple OSS Distributions owners.next = owners.prev = NULL;
173388cc0b97SApple OSS Distributions }
173488cc0b97SApple OSS Distributions
173588cc0b97SApple OSS Distributions IOLockUnlock(gIOUserClientOwnersLock);
173688cc0b97SApple OSS Distributions }
173788cc0b97SApple OSS Distributions
1738a5e72196SApple OSS Distributions
1739a5e72196SApple OSS Distributions extern "C" void
iokit_task_app_suspended_changed(task_t task)1740a5e72196SApple OSS Distributions iokit_task_app_suspended_changed(task_t task)
1741a5e72196SApple OSS Distributions {
1742a5e72196SApple OSS Distributions queue_head_t * taskque;
1743a5e72196SApple OSS Distributions IOUserClientOwner * owner;
1744a5e72196SApple OSS Distributions OSSet * set;
1745a5e72196SApple OSS Distributions
1746a5e72196SApple OSS Distributions IOLockLock(gIOUserClientOwnersLock);
1747a5e72196SApple OSS Distributions
1748a5e72196SApple OSS Distributions taskque = task_io_user_clients(task);
1749a5e72196SApple OSS Distributions set = NULL;
1750a5e72196SApple OSS Distributions queue_iterate(taskque, owner, IOUserClientOwner *, taskLink) {
1751a5e72196SApple OSS Distributions if (!owner->uc->messageAppSuspended) {
1752a5e72196SApple OSS Distributions continue;
1753a5e72196SApple OSS Distributions }
1754a5e72196SApple OSS Distributions if (!set) {
1755a5e72196SApple OSS Distributions set = OSSet::withCapacity(4);
1756a5e72196SApple OSS Distributions if (!set) {
1757a5e72196SApple OSS Distributions break;
1758a5e72196SApple OSS Distributions }
1759a5e72196SApple OSS Distributions }
1760a5e72196SApple OSS Distributions set->setObject(owner->uc);
1761a5e72196SApple OSS Distributions }
1762a5e72196SApple OSS Distributions
1763a5e72196SApple OSS Distributions IOLockUnlock(gIOUserClientOwnersLock);
1764a5e72196SApple OSS Distributions
1765a5e72196SApple OSS Distributions if (set) {
1766a5e72196SApple OSS Distributions set->iterateObjects(^bool (OSObject * obj) {
1767a5e72196SApple OSS Distributions IOUserClient * uc;
1768a5e72196SApple OSS Distributions
1769a5e72196SApple OSS Distributions uc = (typeof(uc))obj;
1770a5e72196SApple OSS Distributions #if 0
1771a5e72196SApple OSS Distributions {
1772a5e72196SApple OSS Distributions OSString * str;
1773a5e72196SApple OSS Distributions str = IOCopyLogNameForPID(task_pid(task));
1774a5e72196SApple OSS Distributions IOLog("iokit_task_app_suspended_changed(%s) %s %d\n", str ? str->getCStringNoCopy() : "",
1775a5e72196SApple OSS Distributions uc->getName(), task_is_app_suspended(task));
1776a5e72196SApple OSS Distributions OSSafeReleaseNULL(str);
1777a5e72196SApple OSS Distributions }
1778a5e72196SApple OSS Distributions #endif
1779a5e72196SApple OSS Distributions uc->message(kIOMessageTaskAppSuspendedChange, NULL);
1780a5e72196SApple OSS Distributions
1781a5e72196SApple OSS Distributions return false;
1782a5e72196SApple OSS Distributions });
1783a5e72196SApple OSS Distributions set->release();
1784a5e72196SApple OSS Distributions }
1785a5e72196SApple OSS Distributions }
1786a5e72196SApple OSS Distributions
178794d3b452SApple OSS Distributions static kern_return_t
iokit_task_terminate_phase1(task_t task)178894d3b452SApple OSS Distributions iokit_task_terminate_phase1(task_t task)
178988cc0b97SApple OSS Distributions {
179088cc0b97SApple OSS Distributions queue_head_t * taskque;
179194d3b452SApple OSS Distributions IOUserClientOwner * iter;
179294d3b452SApple OSS Distributions OSSet * userServers = NULL;
179394d3b452SApple OSS Distributions
179494d3b452SApple OSS Distributions if (!task_is_driver(task)) {
179594d3b452SApple OSS Distributions return KERN_SUCCESS;
179694d3b452SApple OSS Distributions }
179794d3b452SApple OSS Distributions userServers = OSSet::withCapacity(1);
179888cc0b97SApple OSS Distributions
179988cc0b97SApple OSS Distributions IOLockLock(gIOUserClientOwnersLock);
180088cc0b97SApple OSS Distributions
180188cc0b97SApple OSS Distributions taskque = task_io_user_clients(task);
180294d3b452SApple OSS Distributions queue_iterate(taskque, iter, IOUserClientOwner *, taskLink) {
180394d3b452SApple OSS Distributions userServers->setObject(iter->uc);
180494d3b452SApple OSS Distributions }
180594d3b452SApple OSS Distributions IOLockUnlock(gIOUserClientOwnersLock);
180694d3b452SApple OSS Distributions
180794d3b452SApple OSS Distributions if (userServers) {
180894d3b452SApple OSS Distributions IOUserServer * userServer;
180994d3b452SApple OSS Distributions while ((userServer = OSRequiredCast(IOUserServer, userServers->getAnyObject()))) {
181094d3b452SApple OSS Distributions userServer->clientDied();
181194d3b452SApple OSS Distributions userServers->removeObject(userServer);
181294d3b452SApple OSS Distributions }
181394d3b452SApple OSS Distributions userServers->release();
181494d3b452SApple OSS Distributions }
181594d3b452SApple OSS Distributions return KERN_SUCCESS;
181694d3b452SApple OSS Distributions }
181794d3b452SApple OSS Distributions
181894d3b452SApple OSS Distributions static kern_return_t
iokit_task_terminate_phase2(task_t task)181994d3b452SApple OSS Distributions iokit_task_terminate_phase2(task_t task)
182094d3b452SApple OSS Distributions {
182194d3b452SApple OSS Distributions queue_head_t * taskque;
182294d3b452SApple OSS Distributions IOUserClientOwner * owner;
182394d3b452SApple OSS Distributions IOUserClient * dead;
182494d3b452SApple OSS Distributions IOUserClient * uc;
182594d3b452SApple OSS Distributions
182694d3b452SApple OSS Distributions IOLockLock(gIOUserClientOwnersLock);
182794d3b452SApple OSS Distributions taskque = task_io_user_clients(task);
182888cc0b97SApple OSS Distributions dead = NULL;
1829a5e72196SApple OSS Distributions while (!queue_empty(taskque)) {
183088cc0b97SApple OSS Distributions owner = (IOUserClientOwner *)(void *) queue_first(taskque);
183188cc0b97SApple OSS Distributions uc = owner->uc;
183288cc0b97SApple OSS Distributions queue_remove(taskque, owner, IOUserClientOwner *, taskLink);
183388cc0b97SApple OSS Distributions queue_remove(&uc->owners, owner, IOUserClientOwner *, ucLink);
1834a5e72196SApple OSS Distributions if (queue_empty(&uc->owners)) {
183588cc0b97SApple OSS Distributions uc->retain();
183688cc0b97SApple OSS Distributions IOLog("destroying out of band connect for %s\n", uc->getName());
183788cc0b97SApple OSS Distributions // now using the uc queue head as a singly linked queue,
183888cc0b97SApple OSS Distributions // leaving .next as NULL to mark it empty
183988cc0b97SApple OSS Distributions uc->owners.next = NULL;
184088cc0b97SApple OSS Distributions uc->owners.prev = (queue_entry_t) dead;
184188cc0b97SApple OSS Distributions dead = uc;
184288cc0b97SApple OSS Distributions }
1843e6231be0SApple OSS Distributions IOFreeType(owner, IOUserClientOwner);
184488cc0b97SApple OSS Distributions }
184588cc0b97SApple OSS Distributions IOLockUnlock(gIOUserClientOwnersLock);
184688cc0b97SApple OSS Distributions
1847a5e72196SApple OSS Distributions while (dead) {
184888cc0b97SApple OSS Distributions uc = dead;
184988cc0b97SApple OSS Distributions dead = (IOUserClient *)(void *) dead->owners.prev;
185088cc0b97SApple OSS Distributions uc->owners.prev = NULL;
1851a5e72196SApple OSS Distributions if (uc->sharedInstance || !uc->closed) {
1852a5e72196SApple OSS Distributions uc->clientDied();
1853a5e72196SApple OSS Distributions }
185488cc0b97SApple OSS Distributions uc->release();
185588cc0b97SApple OSS Distributions }
185688cc0b97SApple OSS Distributions
1857a5e72196SApple OSS Distributions return KERN_SUCCESS;
185888cc0b97SApple OSS Distributions }
185988cc0b97SApple OSS Distributions
186094d3b452SApple OSS Distributions extern "C" kern_return_t
iokit_task_terminate(task_t task,int phase)186194d3b452SApple OSS Distributions iokit_task_terminate(task_t task, int phase)
186294d3b452SApple OSS Distributions {
186394d3b452SApple OSS Distributions switch (phase) {
186494d3b452SApple OSS Distributions case 1:
186594d3b452SApple OSS Distributions return iokit_task_terminate_phase1(task);
186694d3b452SApple OSS Distributions case 2:
186794d3b452SApple OSS Distributions return iokit_task_terminate_phase2(task);
186894d3b452SApple OSS Distributions default:
186994d3b452SApple OSS Distributions panic("iokit_task_terminate phase %d", phase);
187094d3b452SApple OSS Distributions }
187194d3b452SApple OSS Distributions }
187294d3b452SApple OSS Distributions
1873bb611c8fSApple OSS Distributions struct IOUCFilterPolicy {
1874bb611c8fSApple OSS Distributions task_t task;
1875bb611c8fSApple OSS Distributions io_filter_policy_t filterPolicy;
1876bb611c8fSApple OSS Distributions IOUCFilterPolicy * next;
1877bb611c8fSApple OSS Distributions };
1878bb611c8fSApple OSS Distributions
1879bb611c8fSApple OSS Distributions io_filter_policy_t
filterForTask(task_t task,io_filter_policy_t addFilterPolicy)1880bb611c8fSApple OSS Distributions IOUserClient::filterForTask(task_t task, io_filter_policy_t addFilterPolicy)
1881bb611c8fSApple OSS Distributions {
1882bb611c8fSApple OSS Distributions IOUCFilterPolicy * elem;
1883bb611c8fSApple OSS Distributions io_filter_policy_t filterPolicy;
1884bb611c8fSApple OSS Distributions
1885bb611c8fSApple OSS Distributions filterPolicy = 0;
1886aca3beaaSApple OSS Distributions IOLockLock(&filterLock);
1887bb611c8fSApple OSS Distributions
1888bb611c8fSApple OSS Distributions for (elem = reserved->filterPolicies; elem && (elem->task != task); elem = elem->next) {
1889bb611c8fSApple OSS Distributions }
1890bb611c8fSApple OSS Distributions
1891bb611c8fSApple OSS Distributions if (elem) {
1892bb611c8fSApple OSS Distributions if (addFilterPolicy) {
1893bb611c8fSApple OSS Distributions assert(addFilterPolicy == elem->filterPolicy);
1894bb611c8fSApple OSS Distributions }
1895bb611c8fSApple OSS Distributions filterPolicy = elem->filterPolicy;
1896bb611c8fSApple OSS Distributions } else if (addFilterPolicy) {
1897e6231be0SApple OSS Distributions elem = IOMallocType(IOUCFilterPolicy);
1898bb611c8fSApple OSS Distributions elem->task = task;
1899bb611c8fSApple OSS Distributions elem->filterPolicy = addFilterPolicy;
1900bb611c8fSApple OSS Distributions elem->next = reserved->filterPolicies;
1901bb611c8fSApple OSS Distributions reserved->filterPolicies = elem;
1902bb611c8fSApple OSS Distributions filterPolicy = addFilterPolicy;
1903bb611c8fSApple OSS Distributions }
1904bb611c8fSApple OSS Distributions
1905aca3beaaSApple OSS Distributions IOLockUnlock(&filterLock);
1906bb611c8fSApple OSS Distributions return filterPolicy;
1907bb611c8fSApple OSS Distributions }
1908bb611c8fSApple OSS Distributions
1909a5e72196SApple OSS Distributions void
free()1910a5e72196SApple OSS Distributions IOUserClient::free()
1911c1dac77fSApple OSS Distributions {
1912a5e72196SApple OSS Distributions if (mappings) {
1913a5e72196SApple OSS Distributions mappings->release();
1914a5e72196SApple OSS Distributions }
1915c1dac77fSApple OSS Distributions
1916855239e5SApple OSS Distributions IOStatisticsUnregisterCounter();
1917855239e5SApple OSS Distributions
191888cc0b97SApple OSS Distributions assert(!owners.next);
191988cc0b97SApple OSS Distributions assert(!owners.prev);
192088cc0b97SApple OSS Distributions
1921a5e72196SApple OSS Distributions if (reserved) {
1922bb611c8fSApple OSS Distributions IOUCFilterPolicy * elem;
1923bb611c8fSApple OSS Distributions IOUCFilterPolicy * nextElem;
1924bb611c8fSApple OSS Distributions for (elem = reserved->filterPolicies; elem; elem = nextElem) {
1925bb611c8fSApple OSS Distributions nextElem = elem->next;
1926bb611c8fSApple OSS Distributions if (elem->filterPolicy && gIOUCFilterCallbacks->io_filter_release) {
1927bb611c8fSApple OSS Distributions gIOUCFilterCallbacks->io_filter_release(elem->filterPolicy);
1928bb611c8fSApple OSS Distributions }
1929e6231be0SApple OSS Distributions IOFreeType(elem, IOUCFilterPolicy);
1930bb611c8fSApple OSS Distributions }
1931e6231be0SApple OSS Distributions IOFreeType(reserved, ExpansionData);
1932aca3beaaSApple OSS Distributions IORWLockInlineDestroy(&lock);
1933aca3beaaSApple OSS Distributions IOLockInlineDestroy(&filterLock);
1934a5e72196SApple OSS Distributions }
1935855239e5SApple OSS Distributions
1936c1dac77fSApple OSS Distributions super::free();
1937c1dac77fSApple OSS Distributions }
1938c1dac77fSApple OSS Distributions
19395c2921b0SApple OSS Distributions /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
19405c2921b0SApple OSS Distributions
OSDefineMetaClassAndAbstractStructors(IOUserClient2022,IOUserClient)19415c2921b0SApple OSS Distributions OSDefineMetaClassAndAbstractStructors( IOUserClient2022, IOUserClient )
19425c2921b0SApple OSS Distributions
19435c2921b0SApple OSS Distributions
19445c2921b0SApple OSS Distributions /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
19455c2921b0SApple OSS Distributions
1946a5e72196SApple OSS Distributions IOReturn
1947a5e72196SApple OSS Distributions IOUserClient::clientDied( void )
1948c1dac77fSApple OSS Distributions {
194988cc0b97SApple OSS Distributions IOReturn ret = kIOReturnNotReady;
195088cc0b97SApple OSS Distributions
1951a5e72196SApple OSS Distributions if (sharedInstance || OSCompareAndSwap8(0, 1, &closed)) {
195288cc0b97SApple OSS Distributions ret = clientClose();
195388cc0b97SApple OSS Distributions }
195488cc0b97SApple OSS Distributions
1955a5e72196SApple OSS Distributions return ret;
1956c1dac77fSApple OSS Distributions }
1957c1dac77fSApple OSS Distributions
1958a5e72196SApple OSS Distributions IOReturn
clientClose(void)1959a5e72196SApple OSS Distributions IOUserClient::clientClose( void )
1960c1dac77fSApple OSS Distributions {
1961a5e72196SApple OSS Distributions return kIOReturnUnsupported;
1962c1dac77fSApple OSS Distributions }
1963c1dac77fSApple OSS Distributions
1964a5e72196SApple OSS Distributions IOService *
getService(void)1965a5e72196SApple OSS Distributions IOUserClient::getService( void )
1966c1dac77fSApple OSS Distributions {
1967a5e72196SApple OSS Distributions return NULL;
1968c1dac77fSApple OSS Distributions }
1969c1dac77fSApple OSS Distributions
1970a5e72196SApple OSS Distributions IOReturn
registerNotificationPort(mach_port_t,UInt32,UInt32)1971a5e72196SApple OSS Distributions IOUserClient::registerNotificationPort(
1972c1dac77fSApple OSS Distributions mach_port_t /* port */,
1973c1dac77fSApple OSS Distributions UInt32 /* type */,
1974c1dac77fSApple OSS Distributions UInt32 /* refCon */)
1975c1dac77fSApple OSS Distributions {
1976a5e72196SApple OSS Distributions return kIOReturnUnsupported;
1977c1dac77fSApple OSS Distributions }
1978c1dac77fSApple OSS Distributions
1979a5e72196SApple OSS Distributions IOReturn
registerNotificationPort(mach_port_t port,UInt32 type,io_user_reference_t refCon)1980a5e72196SApple OSS Distributions IOUserClient::registerNotificationPort(
19813ca3bd55SApple OSS Distributions mach_port_t port,
19823ca3bd55SApple OSS Distributions UInt32 type,
19833ca3bd55SApple OSS Distributions io_user_reference_t refCon)
19843ca3bd55SApple OSS Distributions {
1985a5e72196SApple OSS Distributions return registerNotificationPort(port, type, (UInt32) refCon);
19863ca3bd55SApple OSS Distributions }
19873ca3bd55SApple OSS Distributions
1988a5e72196SApple OSS Distributions IOReturn
getNotificationSemaphore(UInt32 notification_type,semaphore_t * semaphore)1989a5e72196SApple OSS Distributions IOUserClient::getNotificationSemaphore( UInt32 notification_type,
1990c1dac77fSApple OSS Distributions semaphore_t * semaphore )
1991c1dac77fSApple OSS Distributions {
1992a5e72196SApple OSS Distributions return kIOReturnUnsupported;
1993c1dac77fSApple OSS Distributions }
1994c1dac77fSApple OSS Distributions
1995a5e72196SApple OSS Distributions IOReturn
connectClient(IOUserClient *)1996a5e72196SApple OSS Distributions IOUserClient::connectClient( IOUserClient * /* client */ )
1997c1dac77fSApple OSS Distributions {
1998a5e72196SApple OSS Distributions return kIOReturnUnsupported;
1999c1dac77fSApple OSS Distributions }
2000c1dac77fSApple OSS Distributions
2001a5e72196SApple OSS Distributions IOReturn
clientMemoryForType(UInt32 type,IOOptionBits * options,IOMemoryDescriptor ** memory)2002a5e72196SApple OSS Distributions IOUserClient::clientMemoryForType( UInt32 type,
2003c1dac77fSApple OSS Distributions IOOptionBits * options,
2004c1dac77fSApple OSS Distributions IOMemoryDescriptor ** memory )
2005c1dac77fSApple OSS Distributions {
2006a5e72196SApple OSS Distributions return kIOReturnUnsupported;
2007c1dac77fSApple OSS Distributions }
2008c1dac77fSApple OSS Distributions
2009bb611c8fSApple OSS Distributions IOReturn
clientMemoryForType(UInt32 type,IOOptionBits * options,OSSharedPtr<IOMemoryDescriptor> & memory)2010bb611c8fSApple OSS Distributions IOUserClient::clientMemoryForType( UInt32 type,
2011bb611c8fSApple OSS Distributions IOOptionBits * options,
2012bb611c8fSApple OSS Distributions OSSharedPtr<IOMemoryDescriptor>& memory )
2013bb611c8fSApple OSS Distributions {
2014bb611c8fSApple OSS Distributions IOMemoryDescriptor* memoryRaw = nullptr;
2015bb611c8fSApple OSS Distributions IOReturn result = clientMemoryForType(type, options, &memoryRaw);
2016bb611c8fSApple OSS Distributions memory.reset(memoryRaw, OSNoRetain);
2017bb611c8fSApple OSS Distributions return result;
2018bb611c8fSApple OSS Distributions }
2019bb611c8fSApple OSS Distributions
20203ca3bd55SApple OSS Distributions #if !__LP64__
2021a5e72196SApple OSS Distributions IOMemoryMap *
mapClientMemory(IOOptionBits type,task_t task,IOOptionBits mapFlags,IOVirtualAddress atAddress)2022a5e72196SApple OSS Distributions IOUserClient::mapClientMemory(
2023c1dac77fSApple OSS Distributions IOOptionBits type,
2024c1dac77fSApple OSS Distributions task_t task,
2025fad439e7SApple OSS Distributions IOOptionBits mapFlags,
2026fad439e7SApple OSS Distributions IOVirtualAddress atAddress )
2027c1dac77fSApple OSS Distributions {
2028a5e72196SApple OSS Distributions return NULL;
2029c1dac77fSApple OSS Distributions }
20303ca3bd55SApple OSS Distributions #endif
2031c1dac77fSApple OSS Distributions
2032a5e72196SApple OSS Distributions IOMemoryMap *
mapClientMemory64(IOOptionBits type,task_t task,IOOptionBits mapFlags,mach_vm_address_t atAddress)2033a5e72196SApple OSS Distributions IOUserClient::mapClientMemory64(
2034e13b1fa5SApple OSS Distributions IOOptionBits type,
2035e13b1fa5SApple OSS Distributions task_t task,
2036e13b1fa5SApple OSS Distributions IOOptionBits mapFlags,
2037e13b1fa5SApple OSS Distributions mach_vm_address_t atAddress )
2038e13b1fa5SApple OSS Distributions {
2039e13b1fa5SApple OSS Distributions IOReturn err;
2040e13b1fa5SApple OSS Distributions IOOptionBits options = 0;
2041a5e72196SApple OSS Distributions IOMemoryDescriptor * memory = NULL;
2042a5e72196SApple OSS Distributions IOMemoryMap * map = NULL;
2043e13b1fa5SApple OSS Distributions
2044e13b1fa5SApple OSS Distributions err = clientMemoryForType((UInt32) type, &options, &memory );
2045e13b1fa5SApple OSS Distributions
2046e13b1fa5SApple OSS Distributions if (memory && (kIOReturnSuccess == err)) {
204788cc0b97SApple OSS Distributions FAKE_STACK_FRAME(getMetaClass());
204888cc0b97SApple OSS Distributions
2049e13b1fa5SApple OSS Distributions options = (options & ~kIOMapUserOptionsMask)
2050e13b1fa5SApple OSS Distributions | (mapFlags & kIOMapUserOptionsMask);
2051e13b1fa5SApple OSS Distributions map = memory->createMappingInTask( task, atAddress, options );
2052e13b1fa5SApple OSS Distributions memory->release();
205388cc0b97SApple OSS Distributions
205488cc0b97SApple OSS Distributions FAKE_STACK_FRAME_END();
2055e13b1fa5SApple OSS Distributions }
2056e13b1fa5SApple OSS Distributions
2057a5e72196SApple OSS Distributions return map;
2058e13b1fa5SApple OSS Distributions }
2059e13b1fa5SApple OSS Distributions
2060a5e72196SApple OSS Distributions IOReturn
exportObjectToClient(task_t task,OSObject * obj,io_object_t * clientObj)2061a5e72196SApple OSS Distributions IOUserClient::exportObjectToClient(task_t task,
2062c1dac77fSApple OSS Distributions OSObject *obj, io_object_t *clientObj)
2063c1dac77fSApple OSS Distributions {
2064c1dac77fSApple OSS Distributions mach_port_name_t name;
2065c1dac77fSApple OSS Distributions
2066c1dac77fSApple OSS Distributions name = IOMachPort::makeSendRightForTask( task, obj, IKOT_IOKIT_OBJECT );
2067c1dac77fSApple OSS Distributions
2068a5e72196SApple OSS Distributions *clientObj = (io_object_t)(uintptr_t) name;
2069cc9a6355SApple OSS Distributions
2070a5e72196SApple OSS Distributions if (obj) {
2071a5e72196SApple OSS Distributions obj->release();
2072a5e72196SApple OSS Distributions }
2073cc9a6355SApple OSS Distributions
2074c1dac77fSApple OSS Distributions return kIOReturnSuccess;
2075c1dac77fSApple OSS Distributions }
2076c1dac77fSApple OSS Distributions
2077a5e72196SApple OSS Distributions IOReturn
copyPortNameForObjectInTask(task_t task,OSObject * obj,mach_port_name_t * port_name)2078a5e72196SApple OSS Distributions IOUserClient::copyPortNameForObjectInTask(task_t task,
2079cc9a6355SApple OSS Distributions OSObject *obj, mach_port_name_t * port_name)
2080cc9a6355SApple OSS Distributions {
2081cc9a6355SApple OSS Distributions mach_port_name_t name;
2082cc9a6355SApple OSS Distributions
2083cc9a6355SApple OSS Distributions name = IOMachPort::makeSendRightForTask( task, obj, IKOT_IOKIT_IDENT );
2084cc9a6355SApple OSS Distributions
2085cc9a6355SApple OSS Distributions *(mach_port_name_t *) port_name = name;
2086cc9a6355SApple OSS Distributions
2087cc9a6355SApple OSS Distributions return kIOReturnSuccess;
2088cc9a6355SApple OSS Distributions }
2089cc9a6355SApple OSS Distributions
2090a5e72196SApple OSS Distributions IOReturn
copyObjectForPortNameInTask(task_t task,mach_port_name_t port_name,OSObject ** obj)2091a5e72196SApple OSS Distributions IOUserClient::copyObjectForPortNameInTask(task_t task, mach_port_name_t port_name,
2092cc9a6355SApple OSS Distributions OSObject **obj)
2093cc9a6355SApple OSS Distributions {
2094cc9a6355SApple OSS Distributions OSObject * object;
2095cc9a6355SApple OSS Distributions
2096cc9a6355SApple OSS Distributions object = iokit_lookup_object_with_port_name(port_name, IKOT_IOKIT_IDENT, task);
2097cc9a6355SApple OSS Distributions
2098cc9a6355SApple OSS Distributions *obj = object;
2099cc9a6355SApple OSS Distributions
2100a5e72196SApple OSS Distributions return object ? kIOReturnSuccess : kIOReturnIPCError;
2101cc9a6355SApple OSS Distributions }
2102cc9a6355SApple OSS Distributions
2103a5e72196SApple OSS Distributions IOReturn
copyObjectForPortNameInTask(task_t task,mach_port_name_t port_name,OSSharedPtr<OSObject> & obj)2104bb611c8fSApple OSS Distributions IOUserClient::copyObjectForPortNameInTask(task_t task, mach_port_name_t port_name,
2105bb611c8fSApple OSS Distributions OSSharedPtr<OSObject>& obj)
2106bb611c8fSApple OSS Distributions {
2107bb611c8fSApple OSS Distributions OSObject* objRaw = NULL;
2108bb611c8fSApple OSS Distributions IOReturn result = copyObjectForPortNameInTask(task, port_name, &objRaw);
2109bb611c8fSApple OSS Distributions obj.reset(objRaw, OSNoRetain);
2110bb611c8fSApple OSS Distributions return result;
2111bb611c8fSApple OSS Distributions }
2112bb611c8fSApple OSS Distributions
2113bb611c8fSApple OSS Distributions IOReturn
adjustPortNameReferencesInTask(task_t task,mach_port_name_t port_name,mach_port_delta_t delta)2114a5e72196SApple OSS Distributions IOUserClient::adjustPortNameReferencesInTask(task_t task, mach_port_name_t port_name, mach_port_delta_t delta)
2115cc9a6355SApple OSS Distributions {
2116a5e72196SApple OSS Distributions return iokit_mod_send_right(task, port_name, delta);
2117cc9a6355SApple OSS Distributions }
2118cc9a6355SApple OSS Distributions
2119a5e72196SApple OSS Distributions IOExternalMethod *
getExternalMethodForIndex(UInt32)2120a5e72196SApple OSS Distributions IOUserClient::getExternalMethodForIndex( UInt32 /* index */)
2121c1dac77fSApple OSS Distributions {
2122a5e72196SApple OSS Distributions return NULL;
2123c1dac77fSApple OSS Distributions }
2124c1dac77fSApple OSS Distributions
2125a5e72196SApple OSS Distributions IOExternalAsyncMethod *
getExternalAsyncMethodForIndex(UInt32)2126a5e72196SApple OSS Distributions IOUserClient::getExternalAsyncMethodForIndex( UInt32 /* index */)
2127c1dac77fSApple OSS Distributions {
2128a5e72196SApple OSS Distributions return NULL;
2129c1dac77fSApple OSS Distributions }
2130c1dac77fSApple OSS Distributions
2131a5e72196SApple OSS Distributions IOExternalTrap *
2132a5e72196SApple OSS Distributions IOUserClient::
getExternalTrapForIndex(UInt32 index)213388cc0b97SApple OSS Distributions getExternalTrapForIndex(UInt32 index)
213488cc0b97SApple OSS Distributions {
213588cc0b97SApple OSS Distributions return NULL;
213688cc0b97SApple OSS Distributions }
213788cc0b97SApple OSS Distributions
213888cc0b97SApple OSS Distributions #pragma clang diagnostic push
213988cc0b97SApple OSS Distributions #pragma clang diagnostic ignored "-Wdeprecated-declarations"
214088cc0b97SApple OSS Distributions
214188cc0b97SApple OSS Distributions // Suppressing the deprecated-declarations warning. Avoiding the use of deprecated
214288cc0b97SApple OSS Distributions // functions can break clients of kexts implementing getExternalMethodForIndex()
2143a5e72196SApple OSS Distributions IOExternalMethod *
2144a5e72196SApple OSS Distributions IOUserClient::
getTargetAndMethodForIndex(IOService ** targetP,UInt32 index)2145c1dac77fSApple OSS Distributions getTargetAndMethodForIndex(IOService **targetP, UInt32 index)
2146c1dac77fSApple OSS Distributions {
2147c1dac77fSApple OSS Distributions IOExternalMethod *method = getExternalMethodForIndex(index);
2148c1dac77fSApple OSS Distributions
2149a5e72196SApple OSS Distributions if (method) {
2150c1dac77fSApple OSS Distributions *targetP = (IOService *) method->object;
2151a5e72196SApple OSS Distributions }
2152c1dac77fSApple OSS Distributions
2153c1dac77fSApple OSS Distributions return method;
2154c1dac77fSApple OSS Distributions }
2155c1dac77fSApple OSS Distributions
2156bb611c8fSApple OSS Distributions IOExternalMethod *
2157bb611c8fSApple OSS Distributions IOUserClient::
getTargetAndMethodForIndex(OSSharedPtr<IOService> & targetP,UInt32 index)2158bb611c8fSApple OSS Distributions getTargetAndMethodForIndex(OSSharedPtr<IOService>& targetP, UInt32 index)
2159bb611c8fSApple OSS Distributions {
2160bb611c8fSApple OSS Distributions IOService* targetPRaw = NULL;
2161bb611c8fSApple OSS Distributions IOExternalMethod* result = getTargetAndMethodForIndex(&targetPRaw, index);
2162bb611c8fSApple OSS Distributions targetP.reset(targetPRaw, OSRetain);
2163bb611c8fSApple OSS Distributions return result;
2164bb611c8fSApple OSS Distributions }
2165bb611c8fSApple OSS Distributions
2166a5e72196SApple OSS Distributions IOExternalAsyncMethod *
2167a5e72196SApple OSS Distributions IOUserClient::
getAsyncTargetAndMethodForIndex(IOService ** targetP,UInt32 index)2168c1dac77fSApple OSS Distributions getAsyncTargetAndMethodForIndex(IOService ** targetP, UInt32 index)
2169c1dac77fSApple OSS Distributions {
2170c1dac77fSApple OSS Distributions IOExternalAsyncMethod *method = getExternalAsyncMethodForIndex(index);
2171c1dac77fSApple OSS Distributions
2172a5e72196SApple OSS Distributions if (method) {
2173c1dac77fSApple OSS Distributions *targetP = (IOService *) method->object;
2174a5e72196SApple OSS Distributions }
2175c1dac77fSApple OSS Distributions
2176c1dac77fSApple OSS Distributions return method;
2177c1dac77fSApple OSS Distributions }
2178c1dac77fSApple OSS Distributions
2179bb611c8fSApple OSS Distributions IOExternalAsyncMethod *
2180bb611c8fSApple OSS Distributions IOUserClient::
getAsyncTargetAndMethodForIndex(OSSharedPtr<IOService> & targetP,UInt32 index)2181bb611c8fSApple OSS Distributions getAsyncTargetAndMethodForIndex(OSSharedPtr<IOService>& targetP, UInt32 index)
2182bb611c8fSApple OSS Distributions {
2183bb611c8fSApple OSS Distributions IOService* targetPRaw = NULL;
2184bb611c8fSApple OSS Distributions IOExternalAsyncMethod* result = getAsyncTargetAndMethodForIndex(&targetPRaw, index);
2185bb611c8fSApple OSS Distributions targetP.reset(targetPRaw, OSRetain);
2186bb611c8fSApple OSS Distributions return result;
2187bb611c8fSApple OSS Distributions }
2188bb611c8fSApple OSS Distributions
2189a5e72196SApple OSS Distributions IOExternalTrap *
2190a5e72196SApple OSS Distributions IOUserClient::
getTargetAndTrapForIndex(IOService ** targetP,UInt32 index)2191c1dac77fSApple OSS Distributions getTargetAndTrapForIndex(IOService ** targetP, UInt32 index)
2192c1dac77fSApple OSS Distributions {
2193c1dac77fSApple OSS Distributions IOExternalTrap *trap = getExternalTrapForIndex(index);
2194c1dac77fSApple OSS Distributions
2195c1dac77fSApple OSS Distributions if (trap) {
2196c1dac77fSApple OSS Distributions *targetP = trap->object;
2197c1dac77fSApple OSS Distributions }
2198c1dac77fSApple OSS Distributions
2199c1dac77fSApple OSS Distributions return trap;
2200c1dac77fSApple OSS Distributions }
220188cc0b97SApple OSS Distributions #pragma clang diagnostic pop
2202c1dac77fSApple OSS Distributions
2203a5e72196SApple OSS Distributions IOReturn
releaseAsyncReference64(OSAsyncReference64 reference)2204a5e72196SApple OSS Distributions IOUserClient::releaseAsyncReference64(OSAsyncReference64 reference)
22053ca3bd55SApple OSS Distributions {
22063ca3bd55SApple OSS Distributions mach_port_t port;
22073ca3bd55SApple OSS Distributions port = (mach_port_t) (reference[0] & ~kIOUCAsync0Flags);
22083ca3bd55SApple OSS Distributions
2209a5e72196SApple OSS Distributions if (MACH_PORT_NULL != port) {
22103ca3bd55SApple OSS Distributions iokit_release_port_send(port);
22113ca3bd55SApple OSS Distributions }
22123ca3bd55SApple OSS Distributions
2213a5e72196SApple OSS Distributions return kIOReturnSuccess;
2214a5e72196SApple OSS Distributions }
2215a5e72196SApple OSS Distributions
2216a5e72196SApple OSS Distributions IOReturn
releaseNotificationPort(mach_port_t port)2217a5e72196SApple OSS Distributions IOUserClient::releaseNotificationPort(mach_port_t port)
22183ca3bd55SApple OSS Distributions {
2219a5e72196SApple OSS Distributions if (MACH_PORT_NULL != port) {
22203ca3bd55SApple OSS Distributions iokit_release_port_send(port);
22213ca3bd55SApple OSS Distributions }
22223ca3bd55SApple OSS Distributions
2223a5e72196SApple OSS Distributions return kIOReturnSuccess;
2224a5e72196SApple OSS Distributions }
2225a5e72196SApple OSS Distributions
2226a5e72196SApple OSS Distributions IOReturn
sendAsyncResult(OSAsyncReference reference,IOReturn result,void * args[],UInt32 numArgs)2227a5e72196SApple OSS Distributions IOUserClient::sendAsyncResult(OSAsyncReference reference,
2228c1dac77fSApple OSS Distributions IOReturn result, void *args[], UInt32 numArgs)
2229c1dac77fSApple OSS Distributions {
2230e13b1fa5SApple OSS Distributions OSAsyncReference64 reference64;
22315c2921b0SApple OSS Distributions OSBoundedArray<io_user_reference_t, kMaxAsyncArgs> args64;
2232e13b1fa5SApple OSS Distributions unsigned int idx;
2233e13b1fa5SApple OSS Distributions
2234a5e72196SApple OSS Distributions if (numArgs > kMaxAsyncArgs) {
2235e13b1fa5SApple OSS Distributions return kIOReturnMessageTooLarge;
2236e13b1fa5SApple OSS Distributions }
2237e13b1fa5SApple OSS Distributions
2238a5e72196SApple OSS Distributions for (idx = 0; idx < kOSAsyncRef64Count; idx++) {
2239a5e72196SApple OSS Distributions reference64[idx] = REF64(reference[idx]);
2240a5e72196SApple OSS Distributions }
2241a5e72196SApple OSS Distributions
2242a5e72196SApple OSS Distributions for (idx = 0; idx < numArgs; idx++) {
2243a5e72196SApple OSS Distributions args64[idx] = REF64(args[idx]);
2244a5e72196SApple OSS Distributions }
2245a5e72196SApple OSS Distributions
22465c2921b0SApple OSS Distributions return sendAsyncResult64(reference64, result, args64.data(), numArgs);
2247a5e72196SApple OSS Distributions }
2248a5e72196SApple OSS Distributions
2249a5e72196SApple OSS Distributions IOReturn
sendAsyncResult64WithOptions(OSAsyncReference64 reference,IOReturn result,io_user_reference_t args[],UInt32 numArgs,IOOptionBits options)2250a5e72196SApple OSS Distributions IOUserClient::sendAsyncResult64WithOptions(OSAsyncReference64 reference,
2251186b8fceSApple OSS Distributions IOReturn result, io_user_reference_t args[], UInt32 numArgs, IOOptionBits options)
2252186b8fceSApple OSS Distributions {
2253186b8fceSApple OSS Distributions return _sendAsyncResult64(reference, result, args, numArgs, options);
2254186b8fceSApple OSS Distributions }
2255186b8fceSApple OSS Distributions
2256a5e72196SApple OSS Distributions IOReturn
sendAsyncResult64(OSAsyncReference64 reference,IOReturn result,io_user_reference_t args[],UInt32 numArgs)2257a5e72196SApple OSS Distributions IOUserClient::sendAsyncResult64(OSAsyncReference64 reference,
2258e13b1fa5SApple OSS Distributions IOReturn result, io_user_reference_t args[], UInt32 numArgs)
2259e13b1fa5SApple OSS Distributions {
2260186b8fceSApple OSS Distributions return _sendAsyncResult64(reference, result, args, numArgs, 0);
2261186b8fceSApple OSS Distributions }
2262186b8fceSApple OSS Distributions
2263a5e72196SApple OSS Distributions IOReturn
_sendAsyncResult64(OSAsyncReference64 reference,IOReturn result,io_user_reference_t args[],UInt32 numArgs,IOOptionBits options)2264a5e72196SApple OSS Distributions IOUserClient::_sendAsyncResult64(OSAsyncReference64 reference,
2265186b8fceSApple OSS Distributions IOReturn result, io_user_reference_t args[], UInt32 numArgs, IOOptionBits options)
2266186b8fceSApple OSS Distributions {
2267a5e72196SApple OSS Distributions struct ReplyMsg {
2268c1dac77fSApple OSS Distributions mach_msg_header_t msgHdr;
2269a5e72196SApple OSS Distributions union{
2270a5e72196SApple OSS Distributions struct{
2271c1dac77fSApple OSS Distributions OSNotificationHeader notifyHdr;
2272c1dac77fSApple OSS Distributions IOAsyncCompletionContent asyncContent;
2273e13b1fa5SApple OSS Distributions uint32_t args[kMaxAsyncArgs];
2274e13b1fa5SApple OSS Distributions } msg32;
2275a5e72196SApple OSS Distributions struct{
2276e13b1fa5SApple OSS Distributions OSNotificationHeader64 notifyHdr;
2277e13b1fa5SApple OSS Distributions IOAsyncCompletionContent asyncContent;
22783ca3bd55SApple OSS Distributions io_user_reference_t args[kMaxAsyncArgs] __attribute__ ((packed));
2279e13b1fa5SApple OSS Distributions } msg64;
2280e13b1fa5SApple OSS Distributions } m;
2281c1dac77fSApple OSS Distributions };
2282c1dac77fSApple OSS Distributions ReplyMsg replyMsg;
2283c1dac77fSApple OSS Distributions mach_port_t replyPort;
2284c1dac77fSApple OSS Distributions kern_return_t kr;
2285c1dac77fSApple OSS Distributions
2286c1dac77fSApple OSS Distributions // If no reply port, do nothing.
2287e13b1fa5SApple OSS Distributions replyPort = (mach_port_t) (reference[0] & ~kIOUCAsync0Flags);
2288a5e72196SApple OSS Distributions if (replyPort == MACH_PORT_NULL) {
2289c1dac77fSApple OSS Distributions return kIOReturnSuccess;
2290a5e72196SApple OSS Distributions }
2291c1dac77fSApple OSS Distributions
2292a5e72196SApple OSS Distributions if (numArgs > kMaxAsyncArgs) {
2293c1dac77fSApple OSS Distributions return kIOReturnMessageTooLarge;
2294a5e72196SApple OSS Distributions }
2295e13b1fa5SApple OSS Distributions
229688cc0b97SApple OSS Distributions bzero(&replyMsg, sizeof(replyMsg));
2297368ad365SApple OSS Distributions replyMsg.msgHdr.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND /*remote*/,
2298368ad365SApple OSS Distributions 0 /*local*/);
2299c1dac77fSApple OSS Distributions replyMsg.msgHdr.msgh_remote_port = replyPort;
2300a5e72196SApple OSS Distributions replyMsg.msgHdr.msgh_local_port = NULL;
2301c1dac77fSApple OSS Distributions replyMsg.msgHdr.msgh_id = kOSNotificationMessageID;
2302a5e72196SApple OSS Distributions if (kIOUCAsync64Flag & reference[0]) {
2303e13b1fa5SApple OSS Distributions replyMsg.msgHdr.msgh_size =
2304e13b1fa5SApple OSS Distributions sizeof(replyMsg.msgHdr) + sizeof(replyMsg.m.msg64)
2305e13b1fa5SApple OSS Distributions - (kMaxAsyncArgs - numArgs) * sizeof(io_user_reference_t);
2306e13b1fa5SApple OSS Distributions replyMsg.m.msg64.notifyHdr.size = sizeof(IOAsyncCompletionContent)
2307e13b1fa5SApple OSS Distributions + numArgs * sizeof(io_user_reference_t);
2308e13b1fa5SApple OSS Distributions replyMsg.m.msg64.notifyHdr.type = kIOAsyncCompletionNotificationType;
2309bb611c8fSApple OSS Distributions /* Copy reference except for reference[0], which is left as 0 from the earlier bzero */
2310bb611c8fSApple OSS Distributions bcopy(&reference[1], &replyMsg.m.msg64.notifyHdr.reference[1], sizeof(OSAsyncReference64) - sizeof(reference[0]));
2311c1dac77fSApple OSS Distributions
2312e13b1fa5SApple OSS Distributions replyMsg.m.msg64.asyncContent.result = result;
2313a5e72196SApple OSS Distributions if (numArgs) {
2314e13b1fa5SApple OSS Distributions bcopy(args, replyMsg.m.msg64.args, numArgs * sizeof(io_user_reference_t));
2315e13b1fa5SApple OSS Distributions }
2316a5e72196SApple OSS Distributions } else {
2317e13b1fa5SApple OSS Distributions unsigned int idx;
2318c1dac77fSApple OSS Distributions
2319e13b1fa5SApple OSS Distributions replyMsg.msgHdr.msgh_size =
2320e13b1fa5SApple OSS Distributions sizeof(replyMsg.msgHdr) + sizeof(replyMsg.m.msg32)
2321e13b1fa5SApple OSS Distributions - (kMaxAsyncArgs - numArgs) * sizeof(uint32_t);
2322e13b1fa5SApple OSS Distributions
2323e13b1fa5SApple OSS Distributions replyMsg.m.msg32.notifyHdr.size = sizeof(IOAsyncCompletionContent)
2324e13b1fa5SApple OSS Distributions + numArgs * sizeof(uint32_t);
2325e13b1fa5SApple OSS Distributions replyMsg.m.msg32.notifyHdr.type = kIOAsyncCompletionNotificationType;
2326e13b1fa5SApple OSS Distributions
2327bb611c8fSApple OSS Distributions /* Skip reference[0] which is left as 0 from the earlier bzero */
2328bb611c8fSApple OSS Distributions for (idx = 1; idx < kOSAsyncRefCount; idx++) {
2329e13b1fa5SApple OSS Distributions replyMsg.m.msg32.notifyHdr.reference[idx] = REF32(reference[idx]);
2330a5e72196SApple OSS Distributions }
2331e13b1fa5SApple OSS Distributions
2332e13b1fa5SApple OSS Distributions replyMsg.m.msg32.asyncContent.result = result;
2333e13b1fa5SApple OSS Distributions
2334a5e72196SApple OSS Distributions for (idx = 0; idx < numArgs; idx++) {
2335e13b1fa5SApple OSS Distributions replyMsg.m.msg32.args[idx] = REF32(args[idx]);
2336e13b1fa5SApple OSS Distributions }
2337a5e72196SApple OSS Distributions }
2338e13b1fa5SApple OSS Distributions
2339186b8fceSApple OSS Distributions if ((options & kIOUserNotifyOptionCanDrop) != 0) {
2340186b8fceSApple OSS Distributions kr = mach_msg_send_from_kernel_with_options( &replyMsg.msgHdr,
2341*8d741a5dSApple OSS Distributions replyMsg.msgHdr.msgh_size, MACH64_SEND_TIMEOUT, MACH_MSG_TIMEOUT_NONE);
2342186b8fceSApple OSS Distributions } else {
2343186b8fceSApple OSS Distributions /* Fail on full queue. */
2344*8d741a5dSApple OSS Distributions kr = mach_msg_send_from_kernel(&replyMsg.msgHdr,
2345c1dac77fSApple OSS Distributions replyMsg.msgHdr.msgh_size);
2346186b8fceSApple OSS Distributions }
2347a5e72196SApple OSS Distributions if ((KERN_SUCCESS != kr) && (MACH_SEND_TIMED_OUT != kr) && !(kIOUCAsyncErrorLoggedFlag & reference[0])) {
234888cc0b97SApple OSS Distributions reference[0] |= kIOUCAsyncErrorLoggedFlag;
2349*8d741a5dSApple OSS Distributions IOLog("%s: mach_msg_send_from_kernel(0x%x)\n", __PRETTY_FUNCTION__, kr );
235088cc0b97SApple OSS Distributions }
2351c1dac77fSApple OSS Distributions return kr;
2352c1dac77fSApple OSS Distributions }
2353c1dac77fSApple OSS Distributions
2354e13b1fa5SApple OSS Distributions
2355c1dac77fSApple OSS Distributions /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2356c1dac77fSApple OSS Distributions
2357c1dac77fSApple OSS Distributions extern "C" {
2358c1dac77fSApple OSS Distributions #define CHECK(cls, obj, out) \
2359c1dac77fSApple OSS Distributions cls * out; \
2360c1dac77fSApple OSS Distributions if( !(out = OSDynamicCast( cls, obj))) \
2361c1dac77fSApple OSS Distributions return( kIOReturnBadArgument )
2362c1dac77fSApple OSS Distributions
23638dd02465SApple OSS Distributions #define CHECKLOCKED(cls, obj, out) \
23648dd02465SApple OSS Distributions IOUserIterator * oIter; \
23658dd02465SApple OSS Distributions cls * out; \
23668dd02465SApple OSS Distributions if( !(oIter = OSDynamicCast(IOUserIterator, obj))) \
23678dd02465SApple OSS Distributions return (kIOReturnBadArgument); \
23688dd02465SApple OSS Distributions if( !(out = OSDynamicCast(cls, oIter->userIteratorObject))) \
23698dd02465SApple OSS Distributions return (kIOReturnBadArgument)
23708dd02465SApple OSS Distributions
2371a3bb9fccSApple OSS Distributions /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2372a3bb9fccSApple OSS Distributions
23730f3703acSApple OSS Distributions // Create a vm_map_copy_t or kalloc'ed data for memory
23740f3703acSApple OSS Distributions // to be copied out. ipc will free after the copyout.
23750f3703acSApple OSS Distributions
2376a5e72196SApple OSS Distributions static kern_return_t
copyoutkdata(const void * data,vm_size_t len,io_buf_ptr_t * buf)2377a5e72196SApple OSS Distributions copyoutkdata( const void * data, vm_size_t len,
23780f3703acSApple OSS Distributions io_buf_ptr_t * buf )
23790f3703acSApple OSS Distributions {
23800f3703acSApple OSS Distributions kern_return_t err;
23810f3703acSApple OSS Distributions vm_map_copy_t copy;
23820f3703acSApple OSS Distributions
23830f3703acSApple OSS Distributions err = vm_map_copyin( kernel_map, CAST_USER_ADDR_T(data), len,
23840f3703acSApple OSS Distributions false /* src_destroy */, ©);
23850f3703acSApple OSS Distributions
23860f3703acSApple OSS Distributions assert( err == KERN_SUCCESS );
2387a5e72196SApple OSS Distributions if (err == KERN_SUCCESS) {
23880f3703acSApple OSS Distributions *buf = (char *) copy;
2389a5e72196SApple OSS Distributions }
23900f3703acSApple OSS Distributions
2391a5e72196SApple OSS Distributions return err;
23920f3703acSApple OSS Distributions }
23930f3703acSApple OSS Distributions
23940f3703acSApple OSS Distributions /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
23950f3703acSApple OSS Distributions
2396a3bb9fccSApple OSS Distributions /* Routine io_server_version */
2397a5e72196SApple OSS Distributions kern_return_t
is_io_server_version(mach_port_t main_port,uint64_t * version)2398a5e72196SApple OSS Distributions is_io_server_version(
23995c2921b0SApple OSS Distributions mach_port_t main_port,
2400a3bb9fccSApple OSS Distributions uint64_t *version)
2401a3bb9fccSApple OSS Distributions {
2402a3bb9fccSApple OSS Distributions *version = IOKIT_SERVER_VERSION;
2403a5e72196SApple OSS Distributions return kIOReturnSuccess;
2404a3bb9fccSApple OSS Distributions }
2405a3bb9fccSApple OSS Distributions
2406c1dac77fSApple OSS Distributions /* Routine io_object_get_class */
2407a5e72196SApple OSS Distributions kern_return_t
is_io_object_get_class(io_object_t object,io_name_t className)2408a5e72196SApple OSS Distributions is_io_object_get_class(
2409c1dac77fSApple OSS Distributions io_object_t object,
2410c1dac77fSApple OSS Distributions io_name_t className )
2411c1dac77fSApple OSS Distributions {
241214e3d835SApple OSS Distributions const OSMetaClass* my_obj = NULL;
241314e3d835SApple OSS Distributions
2414a5e72196SApple OSS Distributions if (!object) {
2415a5e72196SApple OSS Distributions return kIOReturnBadArgument;
2416a5e72196SApple OSS Distributions }
2417c1dac77fSApple OSS Distributions
241814e3d835SApple OSS Distributions my_obj = object->getMetaClass();
241914e3d835SApple OSS Distributions if (!my_obj) {
2420a5e72196SApple OSS Distributions return kIOReturnNotFound;
242114e3d835SApple OSS Distributions }
242214e3d835SApple OSS Distributions
242388cc0b97SApple OSS Distributions strlcpy( className, my_obj->getClassName(), sizeof(io_name_t));
24240f3703acSApple OSS Distributions
2425a5e72196SApple OSS Distributions return kIOReturnSuccess;
2426c1dac77fSApple OSS Distributions }
2427c1dac77fSApple OSS Distributions
242814e3d835SApple OSS Distributions /* Routine io_object_get_superclass */
2429a5e72196SApple OSS Distributions kern_return_t
is_io_object_get_superclass(mach_port_t main_port,io_name_t obj_name,io_name_t class_name)2430a5e72196SApple OSS Distributions is_io_object_get_superclass(
24315c2921b0SApple OSS Distributions mach_port_t main_port,
243214e3d835SApple OSS Distributions io_name_t obj_name,
243314e3d835SApple OSS Distributions io_name_t class_name)
243414e3d835SApple OSS Distributions {
243576e12aa3SApple OSS Distributions IOReturn ret;
243676e12aa3SApple OSS Distributions const OSMetaClass * meta;
243776e12aa3SApple OSS Distributions const OSMetaClass * super;
243876e12aa3SApple OSS Distributions const OSSymbol * name;
243976e12aa3SApple OSS Distributions const char * cstr;
244014e3d835SApple OSS Distributions
2441a5e72196SApple OSS Distributions if (!obj_name || !class_name) {
2442a5e72196SApple OSS Distributions return kIOReturnBadArgument;
2443a5e72196SApple OSS Distributions }
24445c2921b0SApple OSS Distributions if (main_port != main_device_port) {
2445a5e72196SApple OSS Distributions return kIOReturnNotPrivileged;
2446a5e72196SApple OSS Distributions }
244714e3d835SApple OSS Distributions
244876e12aa3SApple OSS Distributions ret = kIOReturnNotFound;
2449a5e72196SApple OSS Distributions meta = NULL;
2450a5e72196SApple OSS Distributions do{
245176e12aa3SApple OSS Distributions name = OSSymbol::withCString(obj_name);
2452a5e72196SApple OSS Distributions if (!name) {
2453a5e72196SApple OSS Distributions break;
2454a5e72196SApple OSS Distributions }
24555c2921b0SApple OSS Distributions meta = OSMetaClass::copyMetaClassWithName(name);
2456a5e72196SApple OSS Distributions if (!meta) {
2457a5e72196SApple OSS Distributions break;
2458a5e72196SApple OSS Distributions }
245976e12aa3SApple OSS Distributions super = meta->getSuperClass();
2460a5e72196SApple OSS Distributions if (!super) {
2461a5e72196SApple OSS Distributions break;
2462a5e72196SApple OSS Distributions }
246376e12aa3SApple OSS Distributions cstr = super->getClassName();
2464a5e72196SApple OSS Distributions if (!cstr) {
2465a5e72196SApple OSS Distributions break;
2466a5e72196SApple OSS Distributions }
246776e12aa3SApple OSS Distributions strlcpy(class_name, cstr, sizeof(io_name_t));
246876e12aa3SApple OSS Distributions ret = kIOReturnSuccess;
2469a5e72196SApple OSS Distributions }while (false);
247014e3d835SApple OSS Distributions
247176e12aa3SApple OSS Distributions OSSafeReleaseNULL(name);
2472a5e72196SApple OSS Distributions if (meta) {
2473a5e72196SApple OSS Distributions meta->releaseMetaClass();
2474a5e72196SApple OSS Distributions }
247514e3d835SApple OSS Distributions
2476a5e72196SApple OSS Distributions return ret;
247714e3d835SApple OSS Distributions }
247814e3d835SApple OSS Distributions
247914e3d835SApple OSS Distributions /* Routine io_object_get_bundle_identifier */
2480a5e72196SApple OSS Distributions kern_return_t
is_io_object_get_bundle_identifier(mach_port_t main_port,io_name_t obj_name,io_name_t bundle_name)2481a5e72196SApple OSS Distributions is_io_object_get_bundle_identifier(
24825c2921b0SApple OSS Distributions mach_port_t main_port,
248314e3d835SApple OSS Distributions io_name_t obj_name,
248414e3d835SApple OSS Distributions io_name_t bundle_name)
248514e3d835SApple OSS Distributions {
248676e12aa3SApple OSS Distributions IOReturn ret;
248776e12aa3SApple OSS Distributions const OSMetaClass * meta;
248876e12aa3SApple OSS Distributions const OSSymbol * name;
248976e12aa3SApple OSS Distributions const OSSymbol * identifier;
249076e12aa3SApple OSS Distributions const char * cstr;
249114e3d835SApple OSS Distributions
2492a5e72196SApple OSS Distributions if (!obj_name || !bundle_name) {
2493a5e72196SApple OSS Distributions return kIOReturnBadArgument;
2494a5e72196SApple OSS Distributions }
24955c2921b0SApple OSS Distributions if (main_port != main_device_port) {
2496a5e72196SApple OSS Distributions return kIOReturnNotPrivileged;
2497a5e72196SApple OSS Distributions }
249814e3d835SApple OSS Distributions
249976e12aa3SApple OSS Distributions ret = kIOReturnNotFound;
2500a5e72196SApple OSS Distributions meta = NULL;
2501a5e72196SApple OSS Distributions do{
250276e12aa3SApple OSS Distributions name = OSSymbol::withCString(obj_name);
2503a5e72196SApple OSS Distributions if (!name) {
2504a5e72196SApple OSS Distributions break;
2505a5e72196SApple OSS Distributions }
25065c2921b0SApple OSS Distributions meta = OSMetaClass::copyMetaClassWithName(name);
2507a5e72196SApple OSS Distributions if (!meta) {
2508a5e72196SApple OSS Distributions break;
2509a5e72196SApple OSS Distributions }
251076e12aa3SApple OSS Distributions identifier = meta->getKmodName();
2511a5e72196SApple OSS Distributions if (!identifier) {
2512a5e72196SApple OSS Distributions break;
2513a5e72196SApple OSS Distributions }
251476e12aa3SApple OSS Distributions cstr = identifier->getCStringNoCopy();
2515a5e72196SApple OSS Distributions if (!cstr) {
2516a5e72196SApple OSS Distributions break;
2517a5e72196SApple OSS Distributions }
2518e13b1fa5SApple OSS Distributions strlcpy(bundle_name, identifier->getCStringNoCopy(), sizeof(io_name_t));
251976e12aa3SApple OSS Distributions ret = kIOReturnSuccess;
2520a5e72196SApple OSS Distributions }while (false);
252114e3d835SApple OSS Distributions
252276e12aa3SApple OSS Distributions OSSafeReleaseNULL(name);
2523a5e72196SApple OSS Distributions if (meta) {
2524a5e72196SApple OSS Distributions meta->releaseMetaClass();
2525a5e72196SApple OSS Distributions }
252676e12aa3SApple OSS Distributions
2527a5e72196SApple OSS Distributions return ret;
252814e3d835SApple OSS Distributions }
252914e3d835SApple OSS Distributions
2530c1dac77fSApple OSS Distributions /* Routine io_object_conforms_to */
2531a5e72196SApple OSS Distributions kern_return_t
is_io_object_conforms_to(io_object_t object,io_name_t className,boolean_t * conforms)2532a5e72196SApple OSS Distributions is_io_object_conforms_to(
2533c1dac77fSApple OSS Distributions io_object_t object,
2534c1dac77fSApple OSS Distributions io_name_t className,
2535c1dac77fSApple OSS Distributions boolean_t *conforms )
2536c1dac77fSApple OSS Distributions {
2537a5e72196SApple OSS Distributions if (!object) {
2538a5e72196SApple OSS Distributions return kIOReturnBadArgument;
2539a5e72196SApple OSS Distributions }
2540c1dac77fSApple OSS Distributions
2541a5e72196SApple OSS Distributions *conforms = (NULL != object->metaCast( className ));
25420f3703acSApple OSS Distributions
2543a5e72196SApple OSS Distributions return kIOReturnSuccess;
2544c1dac77fSApple OSS Distributions }
2545c1dac77fSApple OSS Distributions
2546c1dac77fSApple OSS Distributions /* Routine io_object_get_retain_count */
2547a5e72196SApple OSS Distributions kern_return_t
is_io_object_get_retain_count(io_object_t object,uint32_t * retainCount)2548a5e72196SApple OSS Distributions is_io_object_get_retain_count(
2549c1dac77fSApple OSS Distributions io_object_t object,
2550e13b1fa5SApple OSS Distributions uint32_t *retainCount )
2551c1dac77fSApple OSS Distributions {
2552a5e72196SApple OSS Distributions if (!object) {
2553a5e72196SApple OSS Distributions return kIOReturnBadArgument;
2554a5e72196SApple OSS Distributions }
2555c1dac77fSApple OSS Distributions
2556c1dac77fSApple OSS Distributions *retainCount = object->getRetainCount();
2557a5e72196SApple OSS Distributions return kIOReturnSuccess;
2558c1dac77fSApple OSS Distributions }
2559c1dac77fSApple OSS Distributions
2560c1dac77fSApple OSS Distributions /* Routine io_iterator_next */
2561a5e72196SApple OSS Distributions kern_return_t
is_io_iterator_next(io_object_t iterator,io_object_t * object)2562a5e72196SApple OSS Distributions is_io_iterator_next(
2563c1dac77fSApple OSS Distributions io_object_t iterator,
2564c1dac77fSApple OSS Distributions io_object_t *object )
2565c1dac77fSApple OSS Distributions {
25668dd02465SApple OSS Distributions IOReturn ret;
2567c1dac77fSApple OSS Distributions OSObject * obj;
2568cc9a6355SApple OSS Distributions OSIterator * iter;
2569cc9a6355SApple OSS Distributions IOUserIterator * uiter;
2570c1dac77fSApple OSS Distributions
2571a5e72196SApple OSS Distributions if ((uiter = OSDynamicCast(IOUserIterator, iterator))) {
2572cc9a6355SApple OSS Distributions obj = uiter->copyNextObject();
2573a5e72196SApple OSS Distributions } else if ((iter = OSDynamicCast(OSIterator, iterator))) {
2574c1dac77fSApple OSS Distributions obj = iter->getNextObject();
2575a5e72196SApple OSS Distributions if (obj) {
2576a5e72196SApple OSS Distributions obj->retain();
2577cc9a6355SApple OSS Distributions }
2578a5e72196SApple OSS Distributions } else {
2579a5e72196SApple OSS Distributions return kIOReturnBadArgument;
2580cc9a6355SApple OSS Distributions }
2581cc9a6355SApple OSS Distributions
2582c1dac77fSApple OSS Distributions if (obj) {
2583c1dac77fSApple OSS Distributions *object = obj;
25848dd02465SApple OSS Distributions ret = kIOReturnSuccess;
2585a5e72196SApple OSS Distributions } else {
25868dd02465SApple OSS Distributions ret = kIOReturnNoDevice;
2587a5e72196SApple OSS Distributions }
25888dd02465SApple OSS Distributions
2589a5e72196SApple OSS Distributions return ret;
2590c1dac77fSApple OSS Distributions }
2591c1dac77fSApple OSS Distributions
2592c1dac77fSApple OSS Distributions /* Routine io_iterator_reset */
2593a5e72196SApple OSS Distributions kern_return_t
is_io_iterator_reset(io_object_t iterator)2594a5e72196SApple OSS Distributions is_io_iterator_reset(
2595c1dac77fSApple OSS Distributions io_object_t iterator )
2596c1dac77fSApple OSS Distributions {
2597c1dac77fSApple OSS Distributions CHECK( OSIterator, iterator, iter );
2598c1dac77fSApple OSS Distributions
2599c1dac77fSApple OSS Distributions iter->reset();
2600c1dac77fSApple OSS Distributions
2601a5e72196SApple OSS Distributions return kIOReturnSuccess;
2602c1dac77fSApple OSS Distributions }
2603c1dac77fSApple OSS Distributions
2604c1dac77fSApple OSS Distributions /* Routine io_iterator_is_valid */
2605a5e72196SApple OSS Distributions kern_return_t
is_io_iterator_is_valid(io_object_t iterator,boolean_t * is_valid)2606a5e72196SApple OSS Distributions is_io_iterator_is_valid(
2607c1dac77fSApple OSS Distributions io_object_t iterator,
2608c1dac77fSApple OSS Distributions boolean_t *is_valid )
2609c1dac77fSApple OSS Distributions {
2610c1dac77fSApple OSS Distributions CHECK( OSIterator, iterator, iter );
2611c1dac77fSApple OSS Distributions
2612c1dac77fSApple OSS Distributions *is_valid = iter->isValid();
2613c1dac77fSApple OSS Distributions
2614a5e72196SApple OSS Distributions return kIOReturnSuccess;
2615c1dac77fSApple OSS Distributions }
2616c1dac77fSApple OSS Distributions
2617a5e72196SApple OSS Distributions static kern_return_t
internal_io_service_match_property_table(io_service_t _service,const char * matching,mach_msg_type_number_t matching_size,boolean_t * matches)2618a5e72196SApple OSS Distributions internal_io_service_match_property_table(
2619c1dac77fSApple OSS Distributions io_service_t _service,
2620a3bb9fccSApple OSS Distributions const char * matching,
2621a3bb9fccSApple OSS Distributions mach_msg_type_number_t matching_size,
2622c1dac77fSApple OSS Distributions boolean_t *matches)
2623c1dac77fSApple OSS Distributions {
2624c1dac77fSApple OSS Distributions CHECK( IOService, _service, service );
2625c1dac77fSApple OSS Distributions
2626c1dac77fSApple OSS Distributions kern_return_t kr;
2627c1dac77fSApple OSS Distributions OSObject * obj;
2628c1dac77fSApple OSS Distributions OSDictionary * dict;
2629c1dac77fSApple OSS Distributions
263088cc0b97SApple OSS Distributions assert(matching_size);
2631bb611c8fSApple OSS Distributions
2632bb611c8fSApple OSS Distributions
263388cc0b97SApple OSS Distributions obj = OSUnserializeXML(matching, matching_size);
26348dd02465SApple OSS Distributions
263588cc0b97SApple OSS Distributions if ((dict = OSDynamicCast( OSDictionary, obj))) {
2636bb611c8fSApple OSS Distributions IOTaskRegistryCompatibilityMatching(current_task(), dict);
2637c1dac77fSApple OSS Distributions *matches = service->passiveMatch( dict );
2638c1dac77fSApple OSS Distributions kr = kIOReturnSuccess;
2639a5e72196SApple OSS Distributions } else {
2640c1dac77fSApple OSS Distributions kr = kIOReturnBadArgument;
2641a5e72196SApple OSS Distributions }
2642c1dac77fSApple OSS Distributions
2643a5e72196SApple OSS Distributions if (obj) {
2644c1dac77fSApple OSS Distributions obj->release();
2645a5e72196SApple OSS Distributions }
2646c1dac77fSApple OSS Distributions
2647a5e72196SApple OSS Distributions return kr;
2648c1dac77fSApple OSS Distributions }
2649c1dac77fSApple OSS Distributions
2650a3bb9fccSApple OSS Distributions /* Routine io_service_match_property_table */
2651a5e72196SApple OSS Distributions kern_return_t
is_io_service_match_property_table(io_service_t service,io_string_t matching,boolean_t * matches)2652a5e72196SApple OSS Distributions is_io_service_match_property_table(
2653a3bb9fccSApple OSS Distributions io_service_t service,
2654a3bb9fccSApple OSS Distributions io_string_t matching,
2655a3bb9fccSApple OSS Distributions boolean_t *matches )
2656a3bb9fccSApple OSS Distributions {
2657a5e72196SApple OSS Distributions return kIOReturnUnsupported;
2658a3bb9fccSApple OSS Distributions }
2659a3bb9fccSApple OSS Distributions
2660a3bb9fccSApple OSS Distributions
2661368ad365SApple OSS Distributions /* Routine io_service_match_property_table_ool */
2662a5e72196SApple OSS Distributions kern_return_t
is_io_service_match_property_table_ool(io_object_t service,io_buf_ptr_t matching,mach_msg_type_number_t matchingCnt,kern_return_t * result,boolean_t * matches)2663a5e72196SApple OSS Distributions is_io_service_match_property_table_ool(
2664368ad365SApple OSS Distributions io_object_t service,
2665368ad365SApple OSS Distributions io_buf_ptr_t matching,
2666368ad365SApple OSS Distributions mach_msg_type_number_t matchingCnt,
2667e13b1fa5SApple OSS Distributions kern_return_t *result,
2668368ad365SApple OSS Distributions boolean_t *matches )
2669368ad365SApple OSS Distributions {
2670368ad365SApple OSS Distributions kern_return_t kr;
2671368ad365SApple OSS Distributions vm_offset_t data;
267214e3d835SApple OSS Distributions vm_map_offset_t map_data;
2673368ad365SApple OSS Distributions
267414e3d835SApple OSS Distributions kr = vm_map_copyout( kernel_map, &map_data, (vm_map_copy_t) matching );
267514e3d835SApple OSS Distributions data = CAST_DOWN(vm_offset_t, map_data);
2676368ad365SApple OSS Distributions
2677368ad365SApple OSS Distributions if (KERN_SUCCESS == kr) {
2678368ad365SApple OSS Distributions // must return success after vm_map_copyout() succeeds
2679a3bb9fccSApple OSS Distributions *result = internal_io_service_match_property_table(service,
2680a3bb9fccSApple OSS Distributions (const char *)data, matchingCnt, matches );
2681368ad365SApple OSS Distributions vm_deallocate( kernel_map, data, matchingCnt );
2682368ad365SApple OSS Distributions }
2683368ad365SApple OSS Distributions
2684a5e72196SApple OSS Distributions return kr;
2685368ad365SApple OSS Distributions }
2686368ad365SApple OSS Distributions
2687a3bb9fccSApple OSS Distributions /* Routine io_service_match_property_table_bin */
2688a5e72196SApple OSS Distributions kern_return_t
is_io_service_match_property_table_bin(io_object_t service,io_struct_inband_t matching,mach_msg_type_number_t matchingCnt,boolean_t * matches)2689a5e72196SApple OSS Distributions is_io_service_match_property_table_bin(
2690a3bb9fccSApple OSS Distributions io_object_t service,
2691a3bb9fccSApple OSS Distributions io_struct_inband_t matching,
2692a3bb9fccSApple OSS Distributions mach_msg_type_number_t matchingCnt,
2693a3bb9fccSApple OSS Distributions boolean_t *matches)
2694a3bb9fccSApple OSS Distributions {
2695a5e72196SApple OSS Distributions return internal_io_service_match_property_table(service, matching, matchingCnt, matches);
2696a3bb9fccSApple OSS Distributions }
2697a3bb9fccSApple OSS Distributions
2698a5e72196SApple OSS Distributions static kern_return_t
internal_io_service_get_matching_services(mach_port_t main_port,const char * matching,mach_msg_type_number_t matching_size,io_iterator_t * existing)2699a5e72196SApple OSS Distributions internal_io_service_get_matching_services(
27005c2921b0SApple OSS Distributions mach_port_t main_port,
2701a3bb9fccSApple OSS Distributions const char * matching,
2702a3bb9fccSApple OSS Distributions mach_msg_type_number_t matching_size,
2703c1dac77fSApple OSS Distributions io_iterator_t *existing )
2704c1dac77fSApple OSS Distributions {
2705c1dac77fSApple OSS Distributions kern_return_t kr;
2706c1dac77fSApple OSS Distributions OSObject * obj;
2707c1dac77fSApple OSS Distributions OSDictionary * dict;
2708c1dac77fSApple OSS Distributions
27095c2921b0SApple OSS Distributions if (main_port != main_device_port) {
2710a5e72196SApple OSS Distributions return kIOReturnNotPrivileged;
2711a5e72196SApple OSS Distributions }
2712c1dac77fSApple OSS Distributions
271388cc0b97SApple OSS Distributions assert(matching_size);
271488cc0b97SApple OSS Distributions obj = OSUnserializeXML(matching, matching_size);
271588cc0b97SApple OSS Distributions
2716c1dac77fSApple OSS Distributions if ((dict = OSDynamicCast( OSDictionary, obj))) {
2717bb611c8fSApple OSS Distributions IOTaskRegistryCompatibilityMatching(current_task(), dict);
27188dd02465SApple OSS Distributions *existing = IOUserIterator::withIterator(IOService::getMatchingServices( dict ));
2719c1dac77fSApple OSS Distributions kr = kIOReturnSuccess;
2720a5e72196SApple OSS Distributions } else {
2721c1dac77fSApple OSS Distributions kr = kIOReturnBadArgument;
2722a5e72196SApple OSS Distributions }
2723c1dac77fSApple OSS Distributions
2724a5e72196SApple OSS Distributions if (obj) {
2725c1dac77fSApple OSS Distributions obj->release();
2726a5e72196SApple OSS Distributions }
2727c1dac77fSApple OSS Distributions
2728a5e72196SApple OSS Distributions return kr;
2729c1dac77fSApple OSS Distributions }
2730c1dac77fSApple OSS Distributions
2731a3bb9fccSApple OSS Distributions /* Routine io_service_get_matching_services */
2732a5e72196SApple OSS Distributions kern_return_t
is_io_service_get_matching_services(mach_port_t main_port,io_string_t matching,io_iterator_t * existing)2733a5e72196SApple OSS Distributions is_io_service_get_matching_services(
27345c2921b0SApple OSS Distributions mach_port_t main_port,
2735a3bb9fccSApple OSS Distributions io_string_t matching,
2736a3bb9fccSApple OSS Distributions io_iterator_t *existing )
2737a3bb9fccSApple OSS Distributions {
2738a5e72196SApple OSS Distributions return kIOReturnUnsupported;
2739a3bb9fccSApple OSS Distributions }
2740a3bb9fccSApple OSS Distributions
2741368ad365SApple OSS Distributions /* Routine io_service_get_matching_services_ool */
2742a5e72196SApple OSS Distributions kern_return_t
is_io_service_get_matching_services_ool(mach_port_t main_port,io_buf_ptr_t matching,mach_msg_type_number_t matchingCnt,kern_return_t * result,io_object_t * existing)2743a5e72196SApple OSS Distributions is_io_service_get_matching_services_ool(
27445c2921b0SApple OSS Distributions mach_port_t main_port,
2745368ad365SApple OSS Distributions io_buf_ptr_t matching,
2746368ad365SApple OSS Distributions mach_msg_type_number_t matchingCnt,
2747e13b1fa5SApple OSS Distributions kern_return_t *result,
2748368ad365SApple OSS Distributions io_object_t *existing )
2749368ad365SApple OSS Distributions {
2750368ad365SApple OSS Distributions kern_return_t kr;
2751368ad365SApple OSS Distributions vm_offset_t data;
275214e3d835SApple OSS Distributions vm_map_offset_t map_data;
2753368ad365SApple OSS Distributions
275414e3d835SApple OSS Distributions kr = vm_map_copyout( kernel_map, &map_data, (vm_map_copy_t) matching );
275514e3d835SApple OSS Distributions data = CAST_DOWN(vm_offset_t, map_data);
2756368ad365SApple OSS Distributions
2757368ad365SApple OSS Distributions if (KERN_SUCCESS == kr) {
2758368ad365SApple OSS Distributions // must return success after vm_map_copyout() succeeds
275988cc0b97SApple OSS Distributions // and mig will copy out objects on success
2760a5e72196SApple OSS Distributions *existing = NULL;
27615c2921b0SApple OSS Distributions *result = internal_io_service_get_matching_services(main_port,
2762a3bb9fccSApple OSS Distributions (const char *) data, matchingCnt, existing);
2763368ad365SApple OSS Distributions vm_deallocate( kernel_map, data, matchingCnt );
2764368ad365SApple OSS Distributions }
2765368ad365SApple OSS Distributions
2766a5e72196SApple OSS Distributions return kr;
2767368ad365SApple OSS Distributions }
2768368ad365SApple OSS Distributions
2769a3bb9fccSApple OSS Distributions /* Routine io_service_get_matching_services_bin */
2770a5e72196SApple OSS Distributions kern_return_t
is_io_service_get_matching_services_bin(mach_port_t main_port,io_struct_inband_t matching,mach_msg_type_number_t matchingCnt,io_object_t * existing)2771a5e72196SApple OSS Distributions is_io_service_get_matching_services_bin(
27725c2921b0SApple OSS Distributions mach_port_t main_port,
2773a3bb9fccSApple OSS Distributions io_struct_inband_t matching,
2774a3bb9fccSApple OSS Distributions mach_msg_type_number_t matchingCnt,
2775a3bb9fccSApple OSS Distributions io_object_t *existing)
2776a3bb9fccSApple OSS Distributions {
27775c2921b0SApple OSS Distributions return internal_io_service_get_matching_services(main_port, matching, matchingCnt, existing);
2778a3bb9fccSApple OSS Distributions }
2779a3bb9fccSApple OSS Distributions
2780a3bb9fccSApple OSS Distributions
2781a5e72196SApple OSS Distributions static kern_return_t
internal_io_service_get_matching_service(mach_port_t main_port,const char * matching,mach_msg_type_number_t matching_size,io_service_t * service)2782a5e72196SApple OSS Distributions internal_io_service_get_matching_service(
27835c2921b0SApple OSS Distributions mach_port_t main_port,
2784a3bb9fccSApple OSS Distributions const char * matching,
2785a3bb9fccSApple OSS Distributions mach_msg_type_number_t matching_size,
2786d0c1fef6SApple OSS Distributions io_service_t *service )
2787d0c1fef6SApple OSS Distributions {
2788d0c1fef6SApple OSS Distributions kern_return_t kr;
2789d0c1fef6SApple OSS Distributions OSObject * obj;
2790d0c1fef6SApple OSS Distributions OSDictionary * dict;
2791d0c1fef6SApple OSS Distributions
27925c2921b0SApple OSS Distributions if (main_port != main_device_port) {
2793a5e72196SApple OSS Distributions return kIOReturnNotPrivileged;
2794a5e72196SApple OSS Distributions }
2795d0c1fef6SApple OSS Distributions
279688cc0b97SApple OSS Distributions assert(matching_size);
279788cc0b97SApple OSS Distributions obj = OSUnserializeXML(matching, matching_size);
279888cc0b97SApple OSS Distributions
2799d0c1fef6SApple OSS Distributions if ((dict = OSDynamicCast( OSDictionary, obj))) {
2800bb611c8fSApple OSS Distributions IOTaskRegistryCompatibilityMatching(current_task(), dict);
2801d0c1fef6SApple OSS Distributions *service = IOService::copyMatchingService( dict );
2802d0c1fef6SApple OSS Distributions kr = *service ? kIOReturnSuccess : kIOReturnNotFound;
2803a5e72196SApple OSS Distributions } else {
2804d0c1fef6SApple OSS Distributions kr = kIOReturnBadArgument;
2805a5e72196SApple OSS Distributions }
2806d0c1fef6SApple OSS Distributions
2807a5e72196SApple OSS Distributions if (obj) {
2808d0c1fef6SApple OSS Distributions obj->release();
2809a5e72196SApple OSS Distributions }
2810d0c1fef6SApple OSS Distributions
2811a5e72196SApple OSS Distributions return kr;
2812d0c1fef6SApple OSS Distributions }
2813d0c1fef6SApple OSS Distributions
2814a3bb9fccSApple OSS Distributions /* Routine io_service_get_matching_service */
2815a5e72196SApple OSS Distributions kern_return_t
is_io_service_get_matching_service(mach_port_t main_port,io_string_t matching,io_service_t * service)2816a5e72196SApple OSS Distributions is_io_service_get_matching_service(
28175c2921b0SApple OSS Distributions mach_port_t main_port,
2818a3bb9fccSApple OSS Distributions io_string_t matching,
2819a3bb9fccSApple OSS Distributions io_service_t *service )
2820a3bb9fccSApple OSS Distributions {
2821a5e72196SApple OSS Distributions return kIOReturnUnsupported;
2822a3bb9fccSApple OSS Distributions }
2823a3bb9fccSApple OSS Distributions
2824d0c1fef6SApple OSS Distributions /* Routine io_service_get_matching_services_ool */
2825a5e72196SApple OSS Distributions kern_return_t
is_io_service_get_matching_service_ool(mach_port_t main_port,io_buf_ptr_t matching,mach_msg_type_number_t matchingCnt,kern_return_t * result,io_object_t * service)2826a5e72196SApple OSS Distributions is_io_service_get_matching_service_ool(
28275c2921b0SApple OSS Distributions mach_port_t main_port,
2828d0c1fef6SApple OSS Distributions io_buf_ptr_t matching,
2829d0c1fef6SApple OSS Distributions mach_msg_type_number_t matchingCnt,
2830d0c1fef6SApple OSS Distributions kern_return_t *result,
2831d0c1fef6SApple OSS Distributions io_object_t *service )
2832d0c1fef6SApple OSS Distributions {
2833d0c1fef6SApple OSS Distributions kern_return_t kr;
2834d0c1fef6SApple OSS Distributions vm_offset_t data;
2835d0c1fef6SApple OSS Distributions vm_map_offset_t map_data;
2836d0c1fef6SApple OSS Distributions
2837d0c1fef6SApple OSS Distributions kr = vm_map_copyout( kernel_map, &map_data, (vm_map_copy_t) matching );
2838d0c1fef6SApple OSS Distributions data = CAST_DOWN(vm_offset_t, map_data);
2839d0c1fef6SApple OSS Distributions
2840d0c1fef6SApple OSS Distributions if (KERN_SUCCESS == kr) {
2841d0c1fef6SApple OSS Distributions // must return success after vm_map_copyout() succeeds
284288cc0b97SApple OSS Distributions // and mig will copy out objects on success
2843a5e72196SApple OSS Distributions *service = NULL;
28445c2921b0SApple OSS Distributions *result = internal_io_service_get_matching_service(main_port,
2845a3bb9fccSApple OSS Distributions (const char *) data, matchingCnt, service );
2846d0c1fef6SApple OSS Distributions vm_deallocate( kernel_map, data, matchingCnt );
2847d0c1fef6SApple OSS Distributions }
2848d0c1fef6SApple OSS Distributions
2849a5e72196SApple OSS Distributions return kr;
2850d0c1fef6SApple OSS Distributions }
2851d0c1fef6SApple OSS Distributions
2852a3bb9fccSApple OSS Distributions /* Routine io_service_get_matching_service_bin */
2853a5e72196SApple OSS Distributions kern_return_t
is_io_service_get_matching_service_bin(mach_port_t main_port,io_struct_inband_t matching,mach_msg_type_number_t matchingCnt,io_object_t * service)2854a5e72196SApple OSS Distributions is_io_service_get_matching_service_bin(
28555c2921b0SApple OSS Distributions mach_port_t main_port,
2856a3bb9fccSApple OSS Distributions io_struct_inband_t matching,
2857a3bb9fccSApple OSS Distributions mach_msg_type_number_t matchingCnt,
2858a3bb9fccSApple OSS Distributions io_object_t *service)
2859a3bb9fccSApple OSS Distributions {
28605c2921b0SApple OSS Distributions return internal_io_service_get_matching_service(main_port, matching, matchingCnt, service);
2861a3bb9fccSApple OSS Distributions }
2862d0c1fef6SApple OSS Distributions
2863a5e72196SApple OSS Distributions static kern_return_t
internal_io_service_add_notification(mach_port_t main_port,io_name_t notification_type,const char * matching,size_t matching_size,mach_port_t port,void * reference,vm_size_t referenceSize,bool client64,io_object_t * notification)2864a5e72196SApple OSS Distributions internal_io_service_add_notification(
28655c2921b0SApple OSS Distributions mach_port_t main_port,
2866c1dac77fSApple OSS Distributions io_name_t notification_type,
2867a3bb9fccSApple OSS Distributions const char * matching,
2868a3bb9fccSApple OSS Distributions size_t matching_size,
2869c1dac77fSApple OSS Distributions mach_port_t port,
2870e13b1fa5SApple OSS Distributions void * reference,
2871e13b1fa5SApple OSS Distributions vm_size_t referenceSize,
2872e13b1fa5SApple OSS Distributions bool client64,
2873c1dac77fSApple OSS Distributions io_object_t * notification )
2874c1dac77fSApple OSS Distributions {
2875a5e72196SApple OSS Distributions IOServiceUserNotification * userNotify = NULL;
2876a5e72196SApple OSS Distributions IONotifier * notify = NULL;
2877c1dac77fSApple OSS Distributions const OSSymbol * sym;
2878bb611c8fSApple OSS Distributions OSObject * obj;
2879c1dac77fSApple OSS Distributions OSDictionary * dict;
2880c1dac77fSApple OSS Distributions IOReturn err;
2881bb611c8fSApple OSS Distributions natural_t userMsgType;
2882c1dac77fSApple OSS Distributions
28835c2921b0SApple OSS Distributions if (main_port != main_device_port) {
2884a5e72196SApple OSS Distributions return kIOReturnNotPrivileged;
2885a5e72196SApple OSS Distributions }
2886c1dac77fSApple OSS Distributions
2887c1dac77fSApple OSS Distributions do {
2888c1dac77fSApple OSS Distributions err = kIOReturnNoResources;
2889c1dac77fSApple OSS Distributions
2890a5e72196SApple OSS Distributions if (matching_size > (sizeof(io_struct_inband_t) * 1024)) {
2891a5e72196SApple OSS Distributions return kIOReturnMessageTooLarge;
2892a5e72196SApple OSS Distributions }
2893cc9a6355SApple OSS Distributions
2894a5e72196SApple OSS Distributions if (!(sym = OSSymbol::withCString( notification_type ))) {
2895c1dac77fSApple OSS Distributions err = kIOReturnNoResources;
2896a5e72196SApple OSS Distributions }
2897c1dac77fSApple OSS Distributions
289888cc0b97SApple OSS Distributions assert(matching_size);
2899bb611c8fSApple OSS Distributions obj = OSUnserializeXML(matching, matching_size);
2900bb611c8fSApple OSS Distributions dict = OSDynamicCast(OSDictionary, obj);
2901a3bb9fccSApple OSS Distributions if (!dict) {
2902c1dac77fSApple OSS Distributions err = kIOReturnBadArgument;
2903c1dac77fSApple OSS Distributions continue;
2904c1dac77fSApple OSS Distributions }
2905bb611c8fSApple OSS Distributions IOTaskRegistryCompatibilityMatching(current_task(), dict);
2906c1dac77fSApple OSS Distributions
2907c1dac77fSApple OSS Distributions if ((sym == gIOPublishNotification)
2908a5e72196SApple OSS Distributions || (sym == gIOFirstPublishNotification)) {
2909c1dac77fSApple OSS Distributions userMsgType = kIOServicePublishNotificationType;
2910a5e72196SApple OSS Distributions } else if ((sym == gIOMatchedNotification)
2911a5e72196SApple OSS Distributions || (sym == gIOFirstMatchNotification)) {
2912c1dac77fSApple OSS Distributions userMsgType = kIOServiceMatchedNotificationType;
2913a5e72196SApple OSS Distributions } else if ((sym == gIOTerminatedNotification)
2914a5e72196SApple OSS Distributions || (sym == gIOWillTerminateNotification)) {
2915c1dac77fSApple OSS Distributions userMsgType = kIOServiceTerminatedNotificationType;
2916a5e72196SApple OSS Distributions } else {
2917c1dac77fSApple OSS Distributions userMsgType = kLastIOKitNotificationType;
2918a5e72196SApple OSS Distributions }
2919c1dac77fSApple OSS Distributions
2920c1dac77fSApple OSS Distributions userNotify = new IOServiceUserNotification;
2921c1dac77fSApple OSS Distributions
2922c1dac77fSApple OSS Distributions if (userNotify && !userNotify->init( port, userMsgType,
2923e13b1fa5SApple OSS Distributions reference, referenceSize, client64)) {
2924c1dac77fSApple OSS Distributions userNotify->release();
2925a5e72196SApple OSS Distributions userNotify = NULL;
2926c1dac77fSApple OSS Distributions }
2927a5e72196SApple OSS Distributions if (!userNotify) {
2928c1dac77fSApple OSS Distributions continue;
2929a5e72196SApple OSS Distributions }
2930c1dac77fSApple OSS Distributions
29313ca3bd55SApple OSS Distributions notify = IOService::addMatchingNotification( sym, dict,
2932c1dac77fSApple OSS Distributions &userNotify->_handler, userNotify );
2933c1dac77fSApple OSS Distributions if (notify) {
2934c1dac77fSApple OSS Distributions *notification = userNotify;
2935c1dac77fSApple OSS Distributions userNotify->setNotification( notify );
2936c1dac77fSApple OSS Distributions err = kIOReturnSuccess;
2937a5e72196SApple OSS Distributions } else {
2938c1dac77fSApple OSS Distributions err = kIOReturnUnsupported;
2939a5e72196SApple OSS Distributions }
2940c1dac77fSApple OSS Distributions } while (false);
2941c1dac77fSApple OSS Distributions
2942a5e72196SApple OSS Distributions if ((kIOReturnSuccess != err) && userNotify) {
2943e6231be0SApple OSS Distributions userNotify->setNotification(NULL);
294476e12aa3SApple OSS Distributions userNotify->invalidatePort();
294576e12aa3SApple OSS Distributions userNotify->release();
2946a5e72196SApple OSS Distributions userNotify = NULL;
294776e12aa3SApple OSS Distributions }
294876e12aa3SApple OSS Distributions
2949a5e72196SApple OSS Distributions if (sym) {
2950c1dac77fSApple OSS Distributions sym->release();
2951a5e72196SApple OSS Distributions }
2952bb611c8fSApple OSS Distributions if (obj) {
2953bb611c8fSApple OSS Distributions obj->release();
2954a5e72196SApple OSS Distributions }
2955c1dac77fSApple OSS Distributions
2956a5e72196SApple OSS Distributions return err;
2957c1dac77fSApple OSS Distributions }
2958c1dac77fSApple OSS Distributions
2959e13b1fa5SApple OSS Distributions
2960e13b1fa5SApple OSS Distributions /* Routine io_service_add_notification */
2961a5e72196SApple OSS Distributions kern_return_t
is_io_service_add_notification(mach_port_t main_port,io_name_t notification_type,io_string_t matching,mach_port_t port,io_async_ref_t reference,mach_msg_type_number_t referenceCnt,io_object_t * notification)2962a5e72196SApple OSS Distributions is_io_service_add_notification(
29635c2921b0SApple OSS Distributions mach_port_t main_port,
2964e13b1fa5SApple OSS Distributions io_name_t notification_type,
2965e13b1fa5SApple OSS Distributions io_string_t matching,
2966e13b1fa5SApple OSS Distributions mach_port_t port,
2967e13b1fa5SApple OSS Distributions io_async_ref_t reference,
2968e13b1fa5SApple OSS Distributions mach_msg_type_number_t referenceCnt,
2969e13b1fa5SApple OSS Distributions io_object_t * notification )
2970e13b1fa5SApple OSS Distributions {
2971a5e72196SApple OSS Distributions return kIOReturnUnsupported;
2972e13b1fa5SApple OSS Distributions }
2973e13b1fa5SApple OSS Distributions
2974e13b1fa5SApple OSS Distributions /* Routine io_service_add_notification_64 */
2975a5e72196SApple OSS Distributions kern_return_t
is_io_service_add_notification_64(mach_port_t main_port,io_name_t notification_type,io_string_t matching,mach_port_t wake_port,io_async_ref64_t reference,mach_msg_type_number_t referenceCnt,io_object_t * notification)2976a5e72196SApple OSS Distributions is_io_service_add_notification_64(
29775c2921b0SApple OSS Distributions mach_port_t main_port,
2978e13b1fa5SApple OSS Distributions io_name_t notification_type,
2979e13b1fa5SApple OSS Distributions io_string_t matching,
2980e13b1fa5SApple OSS Distributions mach_port_t wake_port,
2981e13b1fa5SApple OSS Distributions io_async_ref64_t reference,
2982e13b1fa5SApple OSS Distributions mach_msg_type_number_t referenceCnt,
2983e13b1fa5SApple OSS Distributions io_object_t *notification )
2984e13b1fa5SApple OSS Distributions {
2985a5e72196SApple OSS Distributions return kIOReturnUnsupported;
2986e13b1fa5SApple OSS Distributions }
2987e13b1fa5SApple OSS Distributions
2988a3bb9fccSApple OSS Distributions /* Routine io_service_add_notification_bin */
2989a5e72196SApple OSS Distributions kern_return_t
is_io_service_add_notification_bin(mach_port_t main_port,io_name_t notification_type,io_struct_inband_t matching,mach_msg_type_number_t matchingCnt,mach_port_t wake_port,io_async_ref_t reference,mach_msg_type_number_t referenceCnt,io_object_t * notification)2990a5e72196SApple OSS Distributions is_io_service_add_notification_bin
2991a3bb9fccSApple OSS Distributions (
29925c2921b0SApple OSS Distributions mach_port_t main_port,
2993a3bb9fccSApple OSS Distributions io_name_t notification_type,
2994a3bb9fccSApple OSS Distributions io_struct_inband_t matching,
2995a3bb9fccSApple OSS Distributions mach_msg_type_number_t matchingCnt,
2996a3bb9fccSApple OSS Distributions mach_port_t wake_port,
2997a3bb9fccSApple OSS Distributions io_async_ref_t reference,
2998a3bb9fccSApple OSS Distributions mach_msg_type_number_t referenceCnt,
2999a3bb9fccSApple OSS Distributions io_object_t *notification)
3000a3bb9fccSApple OSS Distributions {
3001a5e72196SApple OSS Distributions io_async_ref_t zreference;
3002a5e72196SApple OSS Distributions
3003a5e72196SApple OSS Distributions if (referenceCnt > ASYNC_REF_COUNT) {
3004a5e72196SApple OSS Distributions return kIOReturnBadArgument;
3005a5e72196SApple OSS Distributions }
3006a5e72196SApple OSS Distributions bcopy(&reference[0], &zreference[0], referenceCnt * sizeof(zreference[0]));
3007a5e72196SApple OSS Distributions bzero(&zreference[referenceCnt], (ASYNC_REF_COUNT - referenceCnt) * sizeof(zreference[0]));
3008a5e72196SApple OSS Distributions
30095c2921b0SApple OSS Distributions return internal_io_service_add_notification(main_port, notification_type,
3010a5e72196SApple OSS Distributions matching, matchingCnt, wake_port, &zreference[0], sizeof(io_async_ref_t),
3011a5e72196SApple OSS Distributions false, notification);
3012a3bb9fccSApple OSS Distributions }
3013a3bb9fccSApple OSS Distributions
3014a3bb9fccSApple OSS Distributions /* Routine io_service_add_notification_bin_64 */
3015a5e72196SApple OSS Distributions kern_return_t
is_io_service_add_notification_bin_64(mach_port_t main_port,io_name_t notification_type,io_struct_inband_t matching,mach_msg_type_number_t matchingCnt,mach_port_t wake_port,io_async_ref64_t reference,mach_msg_type_number_t referenceCnt,io_object_t * notification)3016a5e72196SApple OSS Distributions is_io_service_add_notification_bin_64
3017a3bb9fccSApple OSS Distributions (
30185c2921b0SApple OSS Distributions mach_port_t main_port,
3019a3bb9fccSApple OSS Distributions io_name_t notification_type,
3020a3bb9fccSApple OSS Distributions io_struct_inband_t matching,
3021a3bb9fccSApple OSS Distributions mach_msg_type_number_t matchingCnt,
3022a3bb9fccSApple OSS Distributions mach_port_t wake_port,
3023a3bb9fccSApple OSS Distributions io_async_ref64_t reference,
3024a3bb9fccSApple OSS Distributions mach_msg_type_number_t referenceCnt,
3025a3bb9fccSApple OSS Distributions io_object_t *notification)
3026a3bb9fccSApple OSS Distributions {
3027a5e72196SApple OSS Distributions io_async_ref64_t zreference;
3028a5e72196SApple OSS Distributions
3029a5e72196SApple OSS Distributions if (referenceCnt > ASYNC_REF64_COUNT) {
3030a5e72196SApple OSS Distributions return kIOReturnBadArgument;
3031a5e72196SApple OSS Distributions }
3032a5e72196SApple OSS Distributions bcopy(&reference[0], &zreference[0], referenceCnt * sizeof(zreference[0]));
3033a5e72196SApple OSS Distributions bzero(&zreference[referenceCnt], (ASYNC_REF64_COUNT - referenceCnt) * sizeof(zreference[0]));
3034a5e72196SApple OSS Distributions
30355c2921b0SApple OSS Distributions return internal_io_service_add_notification(main_port, notification_type,
3036a5e72196SApple OSS Distributions matching, matchingCnt, wake_port, &zreference[0], sizeof(io_async_ref64_t),
3037a5e72196SApple OSS Distributions true, notification);
3038a3bb9fccSApple OSS Distributions }
3039e13b1fa5SApple OSS Distributions
3040a5e72196SApple OSS Distributions static kern_return_t
internal_io_service_add_notification_ool(mach_port_t main_port,io_name_t notification_type,io_buf_ptr_t matching,mach_msg_type_number_t matchingCnt,mach_port_t wake_port,void * reference,vm_size_t referenceSize,bool client64,kern_return_t * result,io_object_t * notification)3041a5e72196SApple OSS Distributions internal_io_service_add_notification_ool(
30425c2921b0SApple OSS Distributions mach_port_t main_port,
3043368ad365SApple OSS Distributions io_name_t notification_type,
3044368ad365SApple OSS Distributions io_buf_ptr_t matching,
3045368ad365SApple OSS Distributions mach_msg_type_number_t matchingCnt,
3046368ad365SApple OSS Distributions mach_port_t wake_port,
3047e13b1fa5SApple OSS Distributions void * reference,
3048e13b1fa5SApple OSS Distributions vm_size_t referenceSize,
3049e13b1fa5SApple OSS Distributions bool client64,
3050e13b1fa5SApple OSS Distributions kern_return_t *result,
3051368ad365SApple OSS Distributions io_object_t *notification )
3052368ad365SApple OSS Distributions {
3053368ad365SApple OSS Distributions kern_return_t kr;
3054368ad365SApple OSS Distributions vm_offset_t data;
305514e3d835SApple OSS Distributions vm_map_offset_t map_data;
3056368ad365SApple OSS Distributions
305714e3d835SApple OSS Distributions kr = vm_map_copyout( kernel_map, &map_data, (vm_map_copy_t) matching );
305814e3d835SApple OSS Distributions data = CAST_DOWN(vm_offset_t, map_data);
3059368ad365SApple OSS Distributions
3060368ad365SApple OSS Distributions if (KERN_SUCCESS == kr) {
3061368ad365SApple OSS Distributions // must return success after vm_map_copyout() succeeds
306288cc0b97SApple OSS Distributions // and mig will copy out objects on success
3063a5e72196SApple OSS Distributions *notification = NULL;
30645c2921b0SApple OSS Distributions *result = internal_io_service_add_notification( main_port, notification_type,
3065a3bb9fccSApple OSS Distributions (char *) data, matchingCnt, wake_port, reference, referenceSize, client64, notification );
3066368ad365SApple OSS Distributions vm_deallocate( kernel_map, data, matchingCnt );
3067368ad365SApple OSS Distributions }
3068368ad365SApple OSS Distributions
3069a5e72196SApple OSS Distributions return kr;
3070368ad365SApple OSS Distributions }
3071368ad365SApple OSS Distributions
3072e13b1fa5SApple OSS Distributions /* Routine io_service_add_notification_ool */
3073a5e72196SApple OSS Distributions kern_return_t
is_io_service_add_notification_ool(mach_port_t main_port,io_name_t notification_type,io_buf_ptr_t matching,mach_msg_type_number_t matchingCnt,mach_port_t wake_port,io_async_ref_t reference,mach_msg_type_number_t referenceCnt,kern_return_t * result,io_object_t * notification)3074a5e72196SApple OSS Distributions is_io_service_add_notification_ool(
30755c2921b0SApple OSS Distributions mach_port_t main_port,
3076e13b1fa5SApple OSS Distributions io_name_t notification_type,
3077e13b1fa5SApple OSS Distributions io_buf_ptr_t matching,
3078e13b1fa5SApple OSS Distributions mach_msg_type_number_t matchingCnt,
3079e13b1fa5SApple OSS Distributions mach_port_t wake_port,
3080e13b1fa5SApple OSS Distributions io_async_ref_t reference,
3081e13b1fa5SApple OSS Distributions mach_msg_type_number_t referenceCnt,
3082e13b1fa5SApple OSS Distributions kern_return_t *result,
3083e13b1fa5SApple OSS Distributions io_object_t *notification )
3084e13b1fa5SApple OSS Distributions {
3085a5e72196SApple OSS Distributions io_async_ref_t zreference;
3086a5e72196SApple OSS Distributions
3087a5e72196SApple OSS Distributions if (referenceCnt > ASYNC_REF_COUNT) {
3088a5e72196SApple OSS Distributions return kIOReturnBadArgument;
3089a5e72196SApple OSS Distributions }
3090a5e72196SApple OSS Distributions bcopy(&reference[0], &zreference[0], referenceCnt * sizeof(zreference[0]));
3091a5e72196SApple OSS Distributions bzero(&zreference[referenceCnt], (ASYNC_REF_COUNT - referenceCnt) * sizeof(zreference[0]));
3092a5e72196SApple OSS Distributions
30935c2921b0SApple OSS Distributions return internal_io_service_add_notification_ool(main_port, notification_type,
3094a5e72196SApple OSS Distributions matching, matchingCnt, wake_port, &zreference[0], sizeof(io_async_ref_t),
3095a5e72196SApple OSS Distributions false, result, notification);
3096e13b1fa5SApple OSS Distributions }
3097e13b1fa5SApple OSS Distributions
3098e13b1fa5SApple OSS Distributions /* Routine io_service_add_notification_ool_64 */
3099a5e72196SApple OSS Distributions kern_return_t
is_io_service_add_notification_ool_64(mach_port_t main_port,io_name_t notification_type,io_buf_ptr_t matching,mach_msg_type_number_t matchingCnt,mach_port_t wake_port,io_async_ref64_t reference,mach_msg_type_number_t referenceCnt,kern_return_t * result,io_object_t * notification)3100a5e72196SApple OSS Distributions is_io_service_add_notification_ool_64(
31015c2921b0SApple OSS Distributions mach_port_t main_port,
3102e13b1fa5SApple OSS Distributions io_name_t notification_type,
3103e13b1fa5SApple OSS Distributions io_buf_ptr_t matching,
3104e13b1fa5SApple OSS Distributions mach_msg_type_number_t matchingCnt,
3105e13b1fa5SApple OSS Distributions mach_port_t wake_port,
3106e13b1fa5SApple OSS Distributions io_async_ref64_t reference,
3107e13b1fa5SApple OSS Distributions mach_msg_type_number_t referenceCnt,
3108e13b1fa5SApple OSS Distributions kern_return_t *result,
3109e13b1fa5SApple OSS Distributions io_object_t *notification )
3110e13b1fa5SApple OSS Distributions {
3111a5e72196SApple OSS Distributions io_async_ref64_t zreference;
3112a5e72196SApple OSS Distributions
3113a5e72196SApple OSS Distributions if (referenceCnt > ASYNC_REF64_COUNT) {
3114a5e72196SApple OSS Distributions return kIOReturnBadArgument;
3115a5e72196SApple OSS Distributions }
3116a5e72196SApple OSS Distributions bcopy(&reference[0], &zreference[0], referenceCnt * sizeof(zreference[0]));
3117a5e72196SApple OSS Distributions bzero(&zreference[referenceCnt], (ASYNC_REF64_COUNT - referenceCnt) * sizeof(zreference[0]));
3118a5e72196SApple OSS Distributions
31195c2921b0SApple OSS Distributions return internal_io_service_add_notification_ool(main_port, notification_type,
3120a5e72196SApple OSS Distributions matching, matchingCnt, wake_port, &zreference[0], sizeof(io_async_ref64_t),
3121a5e72196SApple OSS Distributions true, result, notification);
3122e13b1fa5SApple OSS Distributions }
3123368ad365SApple OSS Distributions
3124c1dac77fSApple OSS Distributions /* Routine io_service_add_notification_old */
3125a5e72196SApple OSS Distributions kern_return_t
is_io_service_add_notification_old(mach_port_t main_port,io_name_t notification_type,io_string_t matching,mach_port_t port,natural_t ref,io_object_t * notification)3126a5e72196SApple OSS Distributions is_io_service_add_notification_old(
31275c2921b0SApple OSS Distributions mach_port_t main_port,
3128c1dac77fSApple OSS Distributions io_name_t notification_type,
3129c1dac77fSApple OSS Distributions io_string_t matching,
3130c1dac77fSApple OSS Distributions mach_port_t port,
31313ca3bd55SApple OSS Distributions // for binary compatibility reasons, this must be natural_t for ILP32
3132c1dac77fSApple OSS Distributions natural_t ref,
3133c1dac77fSApple OSS Distributions io_object_t * notification )
3134c1dac77fSApple OSS Distributions {
31355c2921b0SApple OSS Distributions return is_io_service_add_notification( main_port, notification_type,
3136a5e72196SApple OSS Distributions matching, port, &ref, 1, notification );
3137c1dac77fSApple OSS Distributions }
3138c1dac77fSApple OSS Distributions
3139e13b1fa5SApple OSS Distributions
3140a5e72196SApple OSS Distributions static kern_return_t
internal_io_service_add_interest_notification(io_object_t _service,io_name_t type_of_interest,mach_port_t port,void * reference,vm_size_t referenceSize,bool client64,io_object_t * notification)3141a5e72196SApple OSS Distributions internal_io_service_add_interest_notification(
3142c1dac77fSApple OSS Distributions io_object_t _service,
3143c1dac77fSApple OSS Distributions io_name_t type_of_interest,
3144c1dac77fSApple OSS Distributions mach_port_t port,
3145e13b1fa5SApple OSS Distributions void * reference,
3146e13b1fa5SApple OSS Distributions vm_size_t referenceSize,
3147e13b1fa5SApple OSS Distributions bool client64,
3148c1dac77fSApple OSS Distributions io_object_t * notification )
3149c1dac77fSApple OSS Distributions {
3150a5e72196SApple OSS Distributions IOServiceMessageUserNotification * userNotify = NULL;
3151a5e72196SApple OSS Distributions IONotifier * notify = NULL;
3152c1dac77fSApple OSS Distributions const OSSymbol * sym;
3153c1dac77fSApple OSS Distributions IOReturn err;
3154c1dac77fSApple OSS Distributions
3155c1dac77fSApple OSS Distributions CHECK( IOService, _service, service );
3156c1dac77fSApple OSS Distributions
3157c1dac77fSApple OSS Distributions err = kIOReturnNoResources;
3158a5e72196SApple OSS Distributions if ((sym = OSSymbol::withCString( type_of_interest ))) {
3159a5e72196SApple OSS Distributions do {
3160c1dac77fSApple OSS Distributions userNotify = new IOServiceMessageUserNotification;
3161c1dac77fSApple OSS Distributions
3162c1dac77fSApple OSS Distributions if (userNotify && !userNotify->init( port, kIOServiceMessageNotificationType,
3163e6231be0SApple OSS Distributions reference, referenceSize, client64 )) {
3164c1dac77fSApple OSS Distributions userNotify->release();
3165a5e72196SApple OSS Distributions userNotify = NULL;
3166c1dac77fSApple OSS Distributions }
3167a5e72196SApple OSS Distributions if (!userNotify) {
3168c1dac77fSApple OSS Distributions continue;
3169a5e72196SApple OSS Distributions }
3170c1dac77fSApple OSS Distributions
3171c1dac77fSApple OSS Distributions notify = service->registerInterest( sym,
3172c1dac77fSApple OSS Distributions &userNotify->_handler, userNotify );
3173c1dac77fSApple OSS Distributions if (notify) {
3174c1dac77fSApple OSS Distributions *notification = userNotify;
3175c1dac77fSApple OSS Distributions userNotify->setNotification( notify );
3176c1dac77fSApple OSS Distributions err = kIOReturnSuccess;
3177a5e72196SApple OSS Distributions } else {
3178c1dac77fSApple OSS Distributions err = kIOReturnUnsupported;
317976e12aa3SApple OSS Distributions }
3180e6231be0SApple OSS Distributions } while (false);
318176e12aa3SApple OSS Distributions
3182a5e72196SApple OSS Distributions sym->release();
3183a5e72196SApple OSS Distributions }
3184a5e72196SApple OSS Distributions
3185a5e72196SApple OSS Distributions if ((kIOReturnSuccess != err) && userNotify) {
3186e6231be0SApple OSS Distributions userNotify->setNotification(NULL);
3187a5e72196SApple OSS Distributions userNotify->invalidatePort();
3188a5e72196SApple OSS Distributions userNotify->release();
3189a5e72196SApple OSS Distributions userNotify = NULL;
3190a5e72196SApple OSS Distributions }
3191a5e72196SApple OSS Distributions
3192a5e72196SApple OSS Distributions return err;
3193c1dac77fSApple OSS Distributions }
3194c1dac77fSApple OSS Distributions
3195e13b1fa5SApple OSS Distributions /* Routine io_service_add_message_notification */
3196a5e72196SApple OSS Distributions kern_return_t
is_io_service_add_interest_notification(io_object_t service,io_name_t type_of_interest,mach_port_t port,io_async_ref_t reference,mach_msg_type_number_t referenceCnt,io_object_t * notification)3197a5e72196SApple OSS Distributions is_io_service_add_interest_notification(
3198e13b1fa5SApple OSS Distributions io_object_t service,
3199e13b1fa5SApple OSS Distributions io_name_t type_of_interest,
3200e13b1fa5SApple OSS Distributions mach_port_t port,
3201e13b1fa5SApple OSS Distributions io_async_ref_t reference,
3202e13b1fa5SApple OSS Distributions mach_msg_type_number_t referenceCnt,
3203e13b1fa5SApple OSS Distributions io_object_t * notification )
3204e13b1fa5SApple OSS Distributions {
3205a5e72196SApple OSS Distributions io_async_ref_t zreference;
3206a5e72196SApple OSS Distributions
3207a5e72196SApple OSS Distributions if (referenceCnt > ASYNC_REF_COUNT) {
3208a5e72196SApple OSS Distributions return kIOReturnBadArgument;
3209a5e72196SApple OSS Distributions }
3210a5e72196SApple OSS Distributions bcopy(&reference[0], &zreference[0], referenceCnt * sizeof(zreference[0]));
3211a5e72196SApple OSS Distributions bzero(&zreference[referenceCnt], (ASYNC_REF_COUNT - referenceCnt) * sizeof(zreference[0]));
3212a5e72196SApple OSS Distributions
3213a5e72196SApple OSS Distributions return internal_io_service_add_interest_notification(service, type_of_interest,
3214a5e72196SApple OSS Distributions port, &zreference[0], sizeof(io_async_ref_t), false, notification);
3215e13b1fa5SApple OSS Distributions }
3216e13b1fa5SApple OSS Distributions
3217e13b1fa5SApple OSS Distributions /* Routine io_service_add_interest_notification_64 */
3218a5e72196SApple OSS Distributions kern_return_t
is_io_service_add_interest_notification_64(io_object_t service,io_name_t type_of_interest,mach_port_t wake_port,io_async_ref64_t reference,mach_msg_type_number_t referenceCnt,io_object_t * notification)3219a5e72196SApple OSS Distributions is_io_service_add_interest_notification_64(
3220e13b1fa5SApple OSS Distributions io_object_t service,
3221e13b1fa5SApple OSS Distributions io_name_t type_of_interest,
3222e13b1fa5SApple OSS Distributions mach_port_t wake_port,
3223e13b1fa5SApple OSS Distributions io_async_ref64_t reference,
3224e13b1fa5SApple OSS Distributions mach_msg_type_number_t referenceCnt,
3225e13b1fa5SApple OSS Distributions io_object_t *notification )
3226e13b1fa5SApple OSS Distributions {
3227a5e72196SApple OSS Distributions io_async_ref64_t zreference;
3228a5e72196SApple OSS Distributions
3229a5e72196SApple OSS Distributions if (referenceCnt > ASYNC_REF64_COUNT) {
3230a5e72196SApple OSS Distributions return kIOReturnBadArgument;
3231a5e72196SApple OSS Distributions }
3232a5e72196SApple OSS Distributions bcopy(&reference[0], &zreference[0], referenceCnt * sizeof(zreference[0]));
3233a5e72196SApple OSS Distributions bzero(&zreference[referenceCnt], (ASYNC_REF64_COUNT - referenceCnt) * sizeof(zreference[0]));
3234a5e72196SApple OSS Distributions
3235a5e72196SApple OSS Distributions return internal_io_service_add_interest_notification(service, type_of_interest,
3236a5e72196SApple OSS Distributions wake_port, &zreference[0], sizeof(io_async_ref64_t), true, notification);
3237e13b1fa5SApple OSS Distributions }
3238e13b1fa5SApple OSS Distributions
3239e13b1fa5SApple OSS Distributions
3240c1dac77fSApple OSS Distributions /* Routine io_service_acknowledge_notification */
3241a5e72196SApple OSS Distributions kern_return_t
is_io_service_acknowledge_notification(io_object_t _service,natural_t notify_ref,natural_t response)3242a5e72196SApple OSS Distributions is_io_service_acknowledge_notification(
3243c1dac77fSApple OSS Distributions io_object_t _service,
3244c1dac77fSApple OSS Distributions natural_t notify_ref,
3245c1dac77fSApple OSS Distributions natural_t response )
3246c1dac77fSApple OSS Distributions {
3247c1dac77fSApple OSS Distributions CHECK( IOService, _service, service );
3248c1dac77fSApple OSS Distributions
3249a5e72196SApple OSS Distributions return service->acknowledgeNotification((IONotificationRef)(uintptr_t) notify_ref,
3250a5e72196SApple OSS Distributions (IOOptionBits) response );
3251c1dac77fSApple OSS Distributions }
3252c1dac77fSApple OSS Distributions
3253c1dac77fSApple OSS Distributions /* Routine io_connect_get_semaphore */
3254a5e72196SApple OSS Distributions kern_return_t
is_io_connect_get_notification_semaphore(io_connect_t connection,natural_t notification_type,semaphore_t * semaphore)3255a5e72196SApple OSS Distributions is_io_connect_get_notification_semaphore(
3256c1dac77fSApple OSS Distributions io_connect_t connection,
3257c1dac77fSApple OSS Distributions natural_t notification_type,
3258c1dac77fSApple OSS Distributions semaphore_t *semaphore )
3259c1dac77fSApple OSS Distributions {
3260bb611c8fSApple OSS Distributions IOReturn ret;
3261c1dac77fSApple OSS Distributions CHECK( IOUserClient, connection, client );
3262c1dac77fSApple OSS Distributions
3263855239e5SApple OSS Distributions IOStatisticsClientCall();
326494d3b452SApple OSS Distributions client->ipcEnter(kIPCLockWrite);
3265bb611c8fSApple OSS Distributions ret = client->getNotificationSemaphore((UInt32) notification_type,
3266a5e72196SApple OSS Distributions semaphore );
326794d3b452SApple OSS Distributions client->ipcExit(kIPCLockWrite);
3268bb611c8fSApple OSS Distributions
3269bb611c8fSApple OSS Distributions return ret;
3270c1dac77fSApple OSS Distributions }
3271c1dac77fSApple OSS Distributions
3272c1dac77fSApple OSS Distributions /* Routine io_registry_get_root_entry */
3273a5e72196SApple OSS Distributions kern_return_t
is_io_registry_get_root_entry(mach_port_t main_port,io_object_t * root)3274a5e72196SApple OSS Distributions is_io_registry_get_root_entry(
32755c2921b0SApple OSS Distributions mach_port_t main_port,
3276c1dac77fSApple OSS Distributions io_object_t *root )
3277c1dac77fSApple OSS Distributions {
3278c1dac77fSApple OSS Distributions IORegistryEntry * entry;
3279c1dac77fSApple OSS Distributions
32805c2921b0SApple OSS Distributions if (main_port != main_device_port) {
3281a5e72196SApple OSS Distributions return kIOReturnNotPrivileged;
3282a5e72196SApple OSS Distributions }
3283c1dac77fSApple OSS Distributions
3284c1dac77fSApple OSS Distributions entry = IORegistryEntry::getRegistryRoot();
3285a5e72196SApple OSS Distributions if (entry) {
3286c1dac77fSApple OSS Distributions entry->retain();
3287a5e72196SApple OSS Distributions }
3288c1dac77fSApple OSS Distributions *root = entry;
3289c1dac77fSApple OSS Distributions
3290a5e72196SApple OSS Distributions return kIOReturnSuccess;
3291c1dac77fSApple OSS Distributions }
3292c1dac77fSApple OSS Distributions
3293c1dac77fSApple OSS Distributions /* Routine io_registry_create_iterator */
3294a5e72196SApple OSS Distributions kern_return_t
is_io_registry_create_iterator(mach_port_t main_port,io_name_t plane,uint32_t options,io_object_t * iterator)3295a5e72196SApple OSS Distributions is_io_registry_create_iterator(
32965c2921b0SApple OSS Distributions mach_port_t main_port,
3297c1dac77fSApple OSS Distributions io_name_t plane,
3298e13b1fa5SApple OSS Distributions uint32_t options,
3299c1dac77fSApple OSS Distributions io_object_t *iterator )
3300c1dac77fSApple OSS Distributions {
33015c2921b0SApple OSS Distributions if (main_port != main_device_port) {
3302a5e72196SApple OSS Distributions return kIOReturnNotPrivileged;
3303a5e72196SApple OSS Distributions }
3304c1dac77fSApple OSS Distributions
33058dd02465SApple OSS Distributions *iterator = IOUserIterator::withIterator(
33068dd02465SApple OSS Distributions IORegistryIterator::iterateOver(
33078dd02465SApple OSS Distributions IORegistryEntry::getPlane( plane ), options ));
3308c1dac77fSApple OSS Distributions
3309a5e72196SApple OSS Distributions return *iterator ? kIOReturnSuccess : kIOReturnBadArgument;
3310c1dac77fSApple OSS Distributions }
3311c1dac77fSApple OSS Distributions
3312c1dac77fSApple OSS Distributions /* Routine io_registry_entry_create_iterator */
3313a5e72196SApple OSS Distributions kern_return_t
is_io_registry_entry_create_iterator(io_object_t registry_entry,io_name_t plane,uint32_t options,io_object_t * iterator)3314a5e72196SApple OSS Distributions is_io_registry_entry_create_iterator(
3315c1dac77fSApple OSS Distributions io_object_t registry_entry,
3316c1dac77fSApple OSS Distributions io_name_t plane,
3317e13b1fa5SApple OSS Distributions uint32_t options,
3318c1dac77fSApple OSS Distributions io_object_t *iterator )
3319c1dac77fSApple OSS Distributions {
3320c1dac77fSApple OSS Distributions CHECK( IORegistryEntry, registry_entry, entry );
3321c1dac77fSApple OSS Distributions
33228dd02465SApple OSS Distributions *iterator = IOUserIterator::withIterator(
33238dd02465SApple OSS Distributions IORegistryIterator::iterateOver( entry,
33248dd02465SApple OSS Distributions IORegistryEntry::getPlane( plane ), options ));
3325c1dac77fSApple OSS Distributions
3326a5e72196SApple OSS Distributions return *iterator ? kIOReturnSuccess : kIOReturnBadArgument;
3327c1dac77fSApple OSS Distributions }
3328c1dac77fSApple OSS Distributions
3329c1dac77fSApple OSS Distributions /* Routine io_registry_iterator_enter */
3330a5e72196SApple OSS Distributions kern_return_t
is_io_registry_iterator_enter_entry(io_object_t iterator)3331a5e72196SApple OSS Distributions is_io_registry_iterator_enter_entry(
3332c1dac77fSApple OSS Distributions io_object_t iterator )
3333c1dac77fSApple OSS Distributions {
33348dd02465SApple OSS Distributions CHECKLOCKED( IORegistryIterator, iterator, iter );
3335c1dac77fSApple OSS Distributions
3336aca3beaaSApple OSS Distributions IOLockLock(&oIter->lock);
3337c1dac77fSApple OSS Distributions iter->enterEntry();
3338aca3beaaSApple OSS Distributions IOLockUnlock(&oIter->lock);
3339c1dac77fSApple OSS Distributions
3340a5e72196SApple OSS Distributions return kIOReturnSuccess;
3341c1dac77fSApple OSS Distributions }
3342c1dac77fSApple OSS Distributions
3343c1dac77fSApple OSS Distributions /* Routine io_registry_iterator_exit */
3344a5e72196SApple OSS Distributions kern_return_t
is_io_registry_iterator_exit_entry(io_object_t iterator)3345a5e72196SApple OSS Distributions is_io_registry_iterator_exit_entry(
3346c1dac77fSApple OSS Distributions io_object_t iterator )
3347c1dac77fSApple OSS Distributions {
3348c1dac77fSApple OSS Distributions bool didIt;
3349c1dac77fSApple OSS Distributions
33508dd02465SApple OSS Distributions CHECKLOCKED( IORegistryIterator, iterator, iter );
3351c1dac77fSApple OSS Distributions
3352aca3beaaSApple OSS Distributions IOLockLock(&oIter->lock);
3353c1dac77fSApple OSS Distributions didIt = iter->exitEntry();
3354aca3beaaSApple OSS Distributions IOLockUnlock(&oIter->lock);
3355c1dac77fSApple OSS Distributions
3356a5e72196SApple OSS Distributions return didIt ? kIOReturnSuccess : kIOReturnNoDevice;
3357c1dac77fSApple OSS Distributions }
3358c1dac77fSApple OSS Distributions
3359c1dac77fSApple OSS Distributions /* Routine io_registry_entry_from_path */
3360a5e72196SApple OSS Distributions kern_return_t
is_io_registry_entry_from_path(mach_port_t main_port,io_string_t path,io_object_t * registry_entry)3361a5e72196SApple OSS Distributions is_io_registry_entry_from_path(
33625c2921b0SApple OSS Distributions mach_port_t main_port,
3363c1dac77fSApple OSS Distributions io_string_t path,
3364c1dac77fSApple OSS Distributions io_object_t *registry_entry )
3365c1dac77fSApple OSS Distributions {
3366c1dac77fSApple OSS Distributions IORegistryEntry * entry;
3367c1dac77fSApple OSS Distributions
33685c2921b0SApple OSS Distributions if (main_port != main_device_port) {
3369a5e72196SApple OSS Distributions return kIOReturnNotPrivileged;
3370a5e72196SApple OSS Distributions }
3371c1dac77fSApple OSS Distributions
3372c1dac77fSApple OSS Distributions entry = IORegistryEntry::fromPath( path );
3373c1dac77fSApple OSS Distributions
3374bb611c8fSApple OSS Distributions if (!entry && IOTaskRegistryCompatibility(current_task())) {
3375bb611c8fSApple OSS Distributions OSDictionary * matching;
3376bb611c8fSApple OSS Distributions const OSObject * objects[2] = { kOSBooleanTrue, NULL };
3377bb611c8fSApple OSS Distributions const OSSymbol * keys[2] = { gIOCompatibilityMatchKey, gIOPathMatchKey };
3378bb611c8fSApple OSS Distributions
3379bb611c8fSApple OSS Distributions objects[1] = OSString::withCStringNoCopy(path);
3380bb611c8fSApple OSS Distributions matching = OSDictionary::withObjects(objects, keys, 2, 2);
3381bb611c8fSApple OSS Distributions if (matching) {
3382bb611c8fSApple OSS Distributions entry = IOService::copyMatchingService(matching);
3383bb611c8fSApple OSS Distributions }
3384bb611c8fSApple OSS Distributions OSSafeReleaseNULL(matching);
3385bb611c8fSApple OSS Distributions OSSafeReleaseNULL(objects[1]);
3386bb611c8fSApple OSS Distributions }
3387bb611c8fSApple OSS Distributions
3388c1dac77fSApple OSS Distributions *registry_entry = entry;
3389c1dac77fSApple OSS Distributions
3390a5e72196SApple OSS Distributions return kIOReturnSuccess;
3391c1dac77fSApple OSS Distributions }
3392c1dac77fSApple OSS Distributions
33930f3703acSApple OSS Distributions
33940f3703acSApple OSS Distributions /* Routine io_registry_entry_from_path */
3395a5e72196SApple OSS Distributions kern_return_t
is_io_registry_entry_from_path_ool(mach_port_t main_port,io_string_inband_t path,io_buf_ptr_t path_ool,mach_msg_type_number_t path_oolCnt,kern_return_t * result,io_object_t * registry_entry)3396a5e72196SApple OSS Distributions is_io_registry_entry_from_path_ool(
33975c2921b0SApple OSS Distributions mach_port_t main_port,
33980f3703acSApple OSS Distributions io_string_inband_t path,
33990f3703acSApple OSS Distributions io_buf_ptr_t path_ool,
34000f3703acSApple OSS Distributions mach_msg_type_number_t path_oolCnt,
34010f3703acSApple OSS Distributions kern_return_t *result,
34020f3703acSApple OSS Distributions io_object_t *registry_entry)
34030f3703acSApple OSS Distributions {
34040f3703acSApple OSS Distributions IORegistryEntry * entry;
34050f3703acSApple OSS Distributions vm_map_offset_t map_data;
34060f3703acSApple OSS Distributions const char * cpath;
34070f3703acSApple OSS Distributions IOReturn res;
34080f3703acSApple OSS Distributions kern_return_t err;
34090f3703acSApple OSS Distributions
34105c2921b0SApple OSS Distributions if (main_port != main_device_port) {
3411a5e72196SApple OSS Distributions return kIOReturnNotPrivileged;
3412a5e72196SApple OSS Distributions }
34130f3703acSApple OSS Distributions
34140f3703acSApple OSS Distributions map_data = 0;
3415a5e72196SApple OSS Distributions entry = NULL;
34160f3703acSApple OSS Distributions res = err = KERN_SUCCESS;
3417a5e72196SApple OSS Distributions if (path[0]) {
3418a5e72196SApple OSS Distributions cpath = path;
3419a5e72196SApple OSS Distributions } else {
3420a5e72196SApple OSS Distributions if (!path_oolCnt) {
3421a5e72196SApple OSS Distributions return kIOReturnBadArgument;
3422a5e72196SApple OSS Distributions }
3423a5e72196SApple OSS Distributions if (path_oolCnt > (sizeof(io_struct_inband_t) * 1024)) {
3424a5e72196SApple OSS Distributions return kIOReturnMessageTooLarge;
3425a5e72196SApple OSS Distributions }
34260f3703acSApple OSS Distributions
34270f3703acSApple OSS Distributions err = vm_map_copyout(kernel_map, &map_data, (vm_map_copy_t) path_ool);
3428a5e72196SApple OSS Distributions if (KERN_SUCCESS == err) {
34290f3703acSApple OSS Distributions // must return success to mig after vm_map_copyout() succeeds, so result is actual
34300f3703acSApple OSS Distributions cpath = CAST_DOWN(const char *, map_data);
3431a5e72196SApple OSS Distributions if (cpath[path_oolCnt - 1]) {
3432a5e72196SApple OSS Distributions res = kIOReturnBadArgument;
3433a5e72196SApple OSS Distributions }
34340f3703acSApple OSS Distributions }
34350f3703acSApple OSS Distributions }
34360f3703acSApple OSS Distributions
3437a5e72196SApple OSS Distributions if ((KERN_SUCCESS == err) && (KERN_SUCCESS == res)) {
34380f3703acSApple OSS Distributions entry = IORegistryEntry::fromPath(cpath);
34390f3703acSApple OSS Distributions res = entry ? kIOReturnSuccess : kIOReturnNotFound;
34400f3703acSApple OSS Distributions }
34410f3703acSApple OSS Distributions
3442a5e72196SApple OSS Distributions if (map_data) {
3443a5e72196SApple OSS Distributions vm_deallocate(kernel_map, map_data, path_oolCnt);
3444a5e72196SApple OSS Distributions }
34450f3703acSApple OSS Distributions
3446a5e72196SApple OSS Distributions if (KERN_SUCCESS != err) {
3447a5e72196SApple OSS Distributions res = err;
3448a5e72196SApple OSS Distributions }
34490f3703acSApple OSS Distributions *registry_entry = entry;
34500f3703acSApple OSS Distributions *result = res;
34510f3703acSApple OSS Distributions
3452a5e72196SApple OSS Distributions return err;
34530f3703acSApple OSS Distributions }
34540f3703acSApple OSS Distributions
34550f3703acSApple OSS Distributions
3456c1dac77fSApple OSS Distributions /* Routine io_registry_entry_in_plane */
3457a5e72196SApple OSS Distributions kern_return_t
is_io_registry_entry_in_plane(io_object_t registry_entry,io_name_t plane,boolean_t * inPlane)3458a5e72196SApple OSS Distributions is_io_registry_entry_in_plane(
3459c1dac77fSApple OSS Distributions io_object_t registry_entry,
3460c1dac77fSApple OSS Distributions io_name_t plane,
3461c1dac77fSApple OSS Distributions boolean_t *inPlane )
3462c1dac77fSApple OSS Distributions {
3463c1dac77fSApple OSS Distributions CHECK( IORegistryEntry, registry_entry, entry );
3464c1dac77fSApple OSS Distributions
3465c1dac77fSApple OSS Distributions *inPlane = entry->inPlane( IORegistryEntry::getPlane( plane ));
3466c1dac77fSApple OSS Distributions
3467a5e72196SApple OSS Distributions return kIOReturnSuccess;
3468c1dac77fSApple OSS Distributions }
3469c1dac77fSApple OSS Distributions
3470c1dac77fSApple OSS Distributions
3471c1dac77fSApple OSS Distributions /* Routine io_registry_entry_get_path */
3472a5e72196SApple OSS Distributions kern_return_t
is_io_registry_entry_get_path(io_object_t registry_entry,io_name_t plane,io_string_t path)3473a5e72196SApple OSS Distributions is_io_registry_entry_get_path(
3474c1dac77fSApple OSS Distributions io_object_t registry_entry,
3475c1dac77fSApple OSS Distributions io_name_t plane,
3476c1dac77fSApple OSS Distributions io_string_t path )
3477c1dac77fSApple OSS Distributions {
3478c1dac77fSApple OSS Distributions int length;
3479c1dac77fSApple OSS Distributions CHECK( IORegistryEntry, registry_entry, entry );
3480c1dac77fSApple OSS Distributions
3481c1dac77fSApple OSS Distributions length = sizeof(io_string_t);
3482a5e72196SApple OSS Distributions if (entry->getPath( path, &length, IORegistryEntry::getPlane( plane ))) {
3483a5e72196SApple OSS Distributions return kIOReturnSuccess;
3484a5e72196SApple OSS Distributions } else {
3485a5e72196SApple OSS Distributions return kIOReturnBadArgument;
3486a5e72196SApple OSS Distributions }
3487c1dac77fSApple OSS Distributions }
3488c1dac77fSApple OSS Distributions
34890f3703acSApple OSS Distributions /* Routine io_registry_entry_get_path */
3490a5e72196SApple OSS Distributions kern_return_t
is_io_registry_entry_get_path_ool(io_object_t registry_entry,io_name_t plane,io_string_inband_t path,io_buf_ptr_t * path_ool,mach_msg_type_number_t * path_oolCnt)3491a5e72196SApple OSS Distributions is_io_registry_entry_get_path_ool(
34920f3703acSApple OSS Distributions io_object_t registry_entry,
34930f3703acSApple OSS Distributions io_name_t plane,
34940f3703acSApple OSS Distributions io_string_inband_t path,
34950f3703acSApple OSS Distributions io_buf_ptr_t *path_ool,
34960f3703acSApple OSS Distributions mach_msg_type_number_t *path_oolCnt)
34970f3703acSApple OSS Distributions {
34980f3703acSApple OSS Distributions enum { kMaxPath = 16384 };
34990f3703acSApple OSS Distributions IOReturn err;
35000f3703acSApple OSS Distributions int length;
35010f3703acSApple OSS Distributions char * buf;
35020f3703acSApple OSS Distributions
35030f3703acSApple OSS Distributions CHECK( IORegistryEntry, registry_entry, entry );
35040f3703acSApple OSS Distributions
35050f3703acSApple OSS Distributions *path_ool = NULL;
35060f3703acSApple OSS Distributions *path_oolCnt = 0;
35070f3703acSApple OSS Distributions length = sizeof(io_string_inband_t);
3508a5e72196SApple OSS Distributions if (entry->getPath(path, &length, IORegistryEntry::getPlane(plane))) {
3509a5e72196SApple OSS Distributions err = kIOReturnSuccess;
3510a5e72196SApple OSS Distributions } else {
35110f3703acSApple OSS Distributions length = kMaxPath;
3512e6231be0SApple OSS Distributions buf = IONewData(char, length);
3513a5e72196SApple OSS Distributions if (!buf) {
3514a5e72196SApple OSS Distributions err = kIOReturnNoMemory;
3515a5e72196SApple OSS Distributions } else if (!entry->getPath(buf, &length, IORegistryEntry::getPlane(plane))) {
3516a5e72196SApple OSS Distributions err = kIOReturnError;
3517a5e72196SApple OSS Distributions } else {
35180f3703acSApple OSS Distributions *path_oolCnt = length;
35190f3703acSApple OSS Distributions err = copyoutkdata(buf, length, path_ool);
35200f3703acSApple OSS Distributions }
3521a5e72196SApple OSS Distributions if (buf) {
3522e6231be0SApple OSS Distributions IODeleteData(buf, char, kMaxPath);
3523a5e72196SApple OSS Distributions }
35240f3703acSApple OSS Distributions }
35250f3703acSApple OSS Distributions
3526a5e72196SApple OSS Distributions return err;
35270f3703acSApple OSS Distributions }
35280f3703acSApple OSS Distributions
3529c1dac77fSApple OSS Distributions
3530c1dac77fSApple OSS Distributions /* Routine io_registry_entry_get_name */
3531a5e72196SApple OSS Distributions kern_return_t
is_io_registry_entry_get_name(io_object_t registry_entry,io_name_t name)3532a5e72196SApple OSS Distributions is_io_registry_entry_get_name(
3533c1dac77fSApple OSS Distributions io_object_t registry_entry,
3534c1dac77fSApple OSS Distributions io_name_t name )
3535c1dac77fSApple OSS Distributions {
3536c1dac77fSApple OSS Distributions CHECK( IORegistryEntry, registry_entry, entry );
3537c1dac77fSApple OSS Distributions
3538c1dac77fSApple OSS Distributions strncpy( name, entry->getName(), sizeof(io_name_t));
3539c1dac77fSApple OSS Distributions
3540a5e72196SApple OSS Distributions return kIOReturnSuccess;
3541c1dac77fSApple OSS Distributions }
3542c1dac77fSApple OSS Distributions
3543c1dac77fSApple OSS Distributions /* Routine io_registry_entry_get_name_in_plane */
3544a5e72196SApple OSS Distributions kern_return_t
is_io_registry_entry_get_name_in_plane(io_object_t registry_entry,io_name_t planeName,io_name_t name)3545a5e72196SApple OSS Distributions is_io_registry_entry_get_name_in_plane(
3546c1dac77fSApple OSS Distributions io_object_t registry_entry,
35478149afccSApple OSS Distributions io_name_t planeName,
3548c1dac77fSApple OSS Distributions io_name_t name )
3549c1dac77fSApple OSS Distributions {
35508149afccSApple OSS Distributions const IORegistryPlane * plane;
3551c1dac77fSApple OSS Distributions CHECK( IORegistryEntry, registry_entry, entry );
3552c1dac77fSApple OSS Distributions
3553a5e72196SApple OSS Distributions if (planeName[0]) {
35548149afccSApple OSS Distributions plane = IORegistryEntry::getPlane( planeName );
3555a5e72196SApple OSS Distributions } else {
3556a5e72196SApple OSS Distributions plane = NULL;
3557a5e72196SApple OSS Distributions }
35588149afccSApple OSS Distributions
35598149afccSApple OSS Distributions strncpy( name, entry->getName( plane), sizeof(io_name_t));
3560c1dac77fSApple OSS Distributions
3561a5e72196SApple OSS Distributions return kIOReturnSuccess;
3562c1dac77fSApple OSS Distributions }
3563c1dac77fSApple OSS Distributions
35648149afccSApple OSS Distributions /* Routine io_registry_entry_get_location_in_plane */
3565a5e72196SApple OSS Distributions kern_return_t
is_io_registry_entry_get_location_in_plane(io_object_t registry_entry,io_name_t planeName,io_name_t location)3566a5e72196SApple OSS Distributions is_io_registry_entry_get_location_in_plane(
35678149afccSApple OSS Distributions io_object_t registry_entry,
35688149afccSApple OSS Distributions io_name_t planeName,
35698149afccSApple OSS Distributions io_name_t location )
35708149afccSApple OSS Distributions {
35718149afccSApple OSS Distributions const IORegistryPlane * plane;
35728149afccSApple OSS Distributions CHECK( IORegistryEntry, registry_entry, entry );
35738149afccSApple OSS Distributions
3574a5e72196SApple OSS Distributions if (planeName[0]) {
35758149afccSApple OSS Distributions plane = IORegistryEntry::getPlane( planeName );
3576a5e72196SApple OSS Distributions } else {
3577a5e72196SApple OSS Distributions plane = NULL;
3578a5e72196SApple OSS Distributions }
35798149afccSApple OSS Distributions
35808149afccSApple OSS Distributions const char * cstr = entry->getLocation( plane );
35818149afccSApple OSS Distributions
35828149afccSApple OSS Distributions if (cstr) {
35838149afccSApple OSS Distributions strncpy( location, cstr, sizeof(io_name_t));
3584a5e72196SApple OSS Distributions return kIOReturnSuccess;
3585a5e72196SApple OSS Distributions } else {
3586a5e72196SApple OSS Distributions return kIOReturnNotFound;
3587a5e72196SApple OSS Distributions }
35888149afccSApple OSS Distributions }
35898149afccSApple OSS Distributions
35903ca3bd55SApple OSS Distributions /* Routine io_registry_entry_get_registry_entry_id */
3591a5e72196SApple OSS Distributions kern_return_t
is_io_registry_entry_get_registry_entry_id(io_object_t registry_entry,uint64_t * entry_id)3592a5e72196SApple OSS Distributions is_io_registry_entry_get_registry_entry_id(
35933ca3bd55SApple OSS Distributions io_object_t registry_entry,
35943ca3bd55SApple OSS Distributions uint64_t *entry_id )
35953ca3bd55SApple OSS Distributions {
35963ca3bd55SApple OSS Distributions CHECK( IORegistryEntry, registry_entry, entry );
35973ca3bd55SApple OSS Distributions
35983ca3bd55SApple OSS Distributions *entry_id = entry->getRegistryEntryID();
35993ca3bd55SApple OSS Distributions
3600a5e72196SApple OSS Distributions return kIOReturnSuccess;
36013ca3bd55SApple OSS Distributions }
36023ca3bd55SApple OSS Distributions
3603bb611c8fSApple OSS Distributions
3604bb611c8fSApple OSS Distributions static OSObject *
IOCopyPropertyCompatible(IORegistryEntry * regEntry,const char * name)3605bb611c8fSApple OSS Distributions IOCopyPropertyCompatible(IORegistryEntry * regEntry, const char * name)
3606bb611c8fSApple OSS Distributions {
3607bb611c8fSApple OSS Distributions OSObject * obj;
3608e6231be0SApple OSS Distributions OSObject * compatProperties;
3609bb611c8fSApple OSS Distributions OSDictionary * props;
3610bb611c8fSApple OSS Distributions
3611bb611c8fSApple OSS Distributions obj = regEntry->copyProperty(name);
3612e6231be0SApple OSS Distributions if (obj) {
3613e6231be0SApple OSS Distributions return obj;
3614e6231be0SApple OSS Distributions }
3615e6231be0SApple OSS Distributions
3616e6231be0SApple OSS Distributions compatProperties = regEntry->copyProperty(gIOUserServicePropertiesKey);
3617e6231be0SApple OSS Distributions if (!compatProperties
3618e6231be0SApple OSS Distributions && IOTaskRegistryCompatibility(current_task())) {
3619e6231be0SApple OSS Distributions compatProperties = regEntry->copyProperty(gIOCompatibilityPropertiesKey);
3620e6231be0SApple OSS Distributions }
3621e6231be0SApple OSS Distributions if (compatProperties) {
3622e6231be0SApple OSS Distributions props = OSDynamicCast(OSDictionary, compatProperties);
3623bb611c8fSApple OSS Distributions if (props) {
3624bb611c8fSApple OSS Distributions obj = props->getObject(name);
3625bb611c8fSApple OSS Distributions if (obj) {
3626bb611c8fSApple OSS Distributions obj->retain();
3627bb611c8fSApple OSS Distributions }
3628bb611c8fSApple OSS Distributions }
3629e6231be0SApple OSS Distributions compatProperties->release();
3630bb611c8fSApple OSS Distributions }
3631bb611c8fSApple OSS Distributions
3632bb611c8fSApple OSS Distributions return obj;
3633bb611c8fSApple OSS Distributions }
3634bb611c8fSApple OSS Distributions
36358149afccSApple OSS Distributions /* Routine io_registry_entry_get_property */
3636a5e72196SApple OSS Distributions kern_return_t
is_io_registry_entry_get_property_bytes(io_object_t registry_entry,io_name_t property_name,io_struct_inband_t buf,mach_msg_type_number_t * dataCnt)3637a5e72196SApple OSS Distributions is_io_registry_entry_get_property_bytes(
36388149afccSApple OSS Distributions io_object_t registry_entry,
36398149afccSApple OSS Distributions io_name_t property_name,
3640e13b1fa5SApple OSS Distributions io_struct_inband_t buf,
36418149afccSApple OSS Distributions mach_msg_type_number_t *dataCnt )
36428149afccSApple OSS Distributions {
36438149afccSApple OSS Distributions OSObject * obj;
36448149afccSApple OSS Distributions OSData * data;
36458149afccSApple OSS Distributions OSString * str;
36468149afccSApple OSS Distributions OSBoolean * boo;
36478149afccSApple OSS Distributions OSNumber * off;
36488149afccSApple OSS Distributions UInt64 offsetBytes;
36498149afccSApple OSS Distributions unsigned int len = 0;
3650a5e72196SApple OSS Distributions const void * bytes = NULL;
36518149afccSApple OSS Distributions IOReturn ret = kIOReturnSuccess;
36528149afccSApple OSS Distributions
36538149afccSApple OSS Distributions CHECK( IORegistryEntry, registry_entry, entry );
36548149afccSApple OSS Distributions
3655a3bb9fccSApple OSS Distributions #if CONFIG_MACF
3656a5e72196SApple OSS Distributions if (0 != mac_iokit_check_get_property(kauth_cred_get(), entry, property_name)) {
3657a3bb9fccSApple OSS Distributions return kIOReturnNotPermitted;
3658a5e72196SApple OSS Distributions }
3659a3bb9fccSApple OSS Distributions #endif
3660a3bb9fccSApple OSS Distributions
3661bb611c8fSApple OSS Distributions obj = IOCopyPropertyCompatible(entry, property_name);
3662a5e72196SApple OSS Distributions if (!obj) {
3663a5e72196SApple OSS Distributions return kIOReturnNoResources;
3664a5e72196SApple OSS Distributions }
36658149afccSApple OSS Distributions
36668149afccSApple OSS Distributions // One day OSData will be a common container base class
36678149afccSApple OSS Distributions // until then...
36688149afccSApple OSS Distributions if ((data = OSDynamicCast( OSData, obj ))) {
36698149afccSApple OSS Distributions len = data->getLength();
36708149afccSApple OSS Distributions bytes = data->getBytesNoCopy();
3671a5e72196SApple OSS Distributions if (!data->isSerializable()) {
3672a5e72196SApple OSS Distributions len = 0;
3673a5e72196SApple OSS Distributions }
36748149afccSApple OSS Distributions } else if ((str = OSDynamicCast( OSString, obj ))) {
36758149afccSApple OSS Distributions len = str->getLength() + 1;
36768149afccSApple OSS Distributions bytes = str->getCStringNoCopy();
36778149afccSApple OSS Distributions } else if ((boo = OSDynamicCast( OSBoolean, obj ))) {
36788149afccSApple OSS Distributions len = boo->isTrue() ? sizeof("Yes") : sizeof("No");
36798149afccSApple OSS Distributions bytes = boo->isTrue() ? "Yes" : "No";
36808149afccSApple OSS Distributions } else if ((off = OSDynamicCast( OSNumber, obj ))) {
36818149afccSApple OSS Distributions offsetBytes = off->unsigned64BitValue();
36828149afccSApple OSS Distributions len = off->numberOfBytes();
3683a5e72196SApple OSS Distributions if (len > sizeof(offsetBytes)) {
3684a5e72196SApple OSS Distributions len = sizeof(offsetBytes);
3685a5e72196SApple OSS Distributions }
36868149afccSApple OSS Distributions bytes = &offsetBytes;
3687368ad365SApple OSS Distributions #ifdef __BIG_ENDIAN__
36888149afccSApple OSS Distributions bytes = (const void *)
36898149afccSApple OSS Distributions (((UInt32) bytes) + (sizeof(UInt64) - len));
36908149afccSApple OSS Distributions #endif
3691a5e72196SApple OSS Distributions } else {
36928149afccSApple OSS Distributions ret = kIOReturnBadArgument;
3693a5e72196SApple OSS Distributions }
36948149afccSApple OSS Distributions
36958149afccSApple OSS Distributions if (bytes) {
3696a5e72196SApple OSS Distributions if (*dataCnt < len) {
36978149afccSApple OSS Distributions ret = kIOReturnIPCError;
3698a5e72196SApple OSS Distributions } else {
36998149afccSApple OSS Distributions *dataCnt = len;
37008149afccSApple OSS Distributions bcopy( bytes, buf, len );
37018149afccSApple OSS Distributions }
37028149afccSApple OSS Distributions }
37038149afccSApple OSS Distributions obj->release();
37048149afccSApple OSS Distributions
3705a5e72196SApple OSS Distributions return ret;
37068149afccSApple OSS Distributions }
37078149afccSApple OSS Distributions
3708e13b1fa5SApple OSS Distributions
37098149afccSApple OSS Distributions /* Routine io_registry_entry_get_property */
3710a5e72196SApple OSS Distributions kern_return_t
is_io_registry_entry_get_property(io_object_t registry_entry,io_name_t property_name,io_buf_ptr_t * properties,mach_msg_type_number_t * propertiesCnt)3711a5e72196SApple OSS Distributions is_io_registry_entry_get_property(
37128149afccSApple OSS Distributions io_object_t registry_entry,
37138149afccSApple OSS Distributions io_name_t property_name,
37148149afccSApple OSS Distributions io_buf_ptr_t *properties,
37158149afccSApple OSS Distributions mach_msg_type_number_t *propertiesCnt )
37168149afccSApple OSS Distributions {
37178149afccSApple OSS Distributions kern_return_t err;
3718bb611c8fSApple OSS Distributions unsigned int len;
37198149afccSApple OSS Distributions OSObject * obj;
37208149afccSApple OSS Distributions
37218149afccSApple OSS Distributions CHECK( IORegistryEntry, registry_entry, entry );
37228149afccSApple OSS Distributions
3723a3bb9fccSApple OSS Distributions #if CONFIG_MACF
3724a5e72196SApple OSS Distributions if (0 != mac_iokit_check_get_property(kauth_cred_get(), entry, property_name)) {
3725a3bb9fccSApple OSS Distributions return kIOReturnNotPermitted;
3726a5e72196SApple OSS Distributions }
3727a3bb9fccSApple OSS Distributions #endif
3728a3bb9fccSApple OSS Distributions
3729bb611c8fSApple OSS Distributions obj = IOCopyPropertyCompatible(entry, property_name);
3730a5e72196SApple OSS Distributions if (!obj) {
3731a5e72196SApple OSS Distributions return kIOReturnNotFound;
3732a5e72196SApple OSS Distributions }
37338149afccSApple OSS Distributions
37348149afccSApple OSS Distributions OSSerialize * s = OSSerialize::withCapacity(4096);
37358149afccSApple OSS Distributions if (!s) {
37368149afccSApple OSS Distributions obj->release();
3737a5e72196SApple OSS Distributions return kIOReturnNoMemory;
37388149afccSApple OSS Distributions }
37398149afccSApple OSS Distributions
37408149afccSApple OSS Distributions if (obj->serialize( s )) {
37418149afccSApple OSS Distributions len = s->getLength();
37428149afccSApple OSS Distributions *propertiesCnt = len;
37438149afccSApple OSS Distributions err = copyoutkdata( s->text(), len, properties );
3744a5e72196SApple OSS Distributions } else {
37458149afccSApple OSS Distributions err = kIOReturnUnsupported;
3746a5e72196SApple OSS Distributions }
37478149afccSApple OSS Distributions
37488149afccSApple OSS Distributions s->release();
37498149afccSApple OSS Distributions obj->release();
37508149afccSApple OSS Distributions
3751a5e72196SApple OSS Distributions return err;
37528149afccSApple OSS Distributions }
37538149afccSApple OSS Distributions
37548149afccSApple OSS Distributions /* Routine io_registry_entry_get_property_recursively */
3755a5e72196SApple OSS Distributions kern_return_t
is_io_registry_entry_get_property_recursively(io_object_t registry_entry,io_name_t plane,io_name_t property_name,uint32_t options,io_buf_ptr_t * properties,mach_msg_type_number_t * propertiesCnt)3756a5e72196SApple OSS Distributions is_io_registry_entry_get_property_recursively(
37578149afccSApple OSS Distributions io_object_t registry_entry,
37588149afccSApple OSS Distributions io_name_t plane,
37598149afccSApple OSS Distributions io_name_t property_name,
3760e13b1fa5SApple OSS Distributions uint32_t options,
37618149afccSApple OSS Distributions io_buf_ptr_t *properties,
37628149afccSApple OSS Distributions mach_msg_type_number_t *propertiesCnt )
37638149afccSApple OSS Distributions {
37648149afccSApple OSS Distributions kern_return_t err;
3765bb611c8fSApple OSS Distributions unsigned int len;
37668149afccSApple OSS Distributions OSObject * obj;
37678149afccSApple OSS Distributions
37688149afccSApple OSS Distributions CHECK( IORegistryEntry, registry_entry, entry );
37698149afccSApple OSS Distributions
3770a3bb9fccSApple OSS Distributions #if CONFIG_MACF
3771a5e72196SApple OSS Distributions if (0 != mac_iokit_check_get_property(kauth_cred_get(), entry, property_name)) {
3772a3bb9fccSApple OSS Distributions return kIOReturnNotPermitted;
3773a5e72196SApple OSS Distributions }
3774a3bb9fccSApple OSS Distributions #endif
3775a3bb9fccSApple OSS Distributions
37768149afccSApple OSS Distributions obj = entry->copyProperty( property_name,
37778149afccSApple OSS Distributions IORegistryEntry::getPlane( plane ), options );
3778a5e72196SApple OSS Distributions if (!obj) {
3779a5e72196SApple OSS Distributions return kIOReturnNotFound;
3780a5e72196SApple OSS Distributions }
37818149afccSApple OSS Distributions
37828149afccSApple OSS Distributions OSSerialize * s = OSSerialize::withCapacity(4096);
37838149afccSApple OSS Distributions if (!s) {
37848149afccSApple OSS Distributions obj->release();
3785a5e72196SApple OSS Distributions return kIOReturnNoMemory;
37868149afccSApple OSS Distributions }
37878149afccSApple OSS Distributions
37888149afccSApple OSS Distributions if (obj->serialize( s )) {
37898149afccSApple OSS Distributions len = s->getLength();
37908149afccSApple OSS Distributions *propertiesCnt = len;
37918149afccSApple OSS Distributions err = copyoutkdata( s->text(), len, properties );
3792a5e72196SApple OSS Distributions } else {
37938149afccSApple OSS Distributions err = kIOReturnUnsupported;
3794a5e72196SApple OSS Distributions }
37958149afccSApple OSS Distributions
37968149afccSApple OSS Distributions s->release();
37978149afccSApple OSS Distributions obj->release();
37988149afccSApple OSS Distributions
3799a5e72196SApple OSS Distributions return err;
38008149afccSApple OSS Distributions }
3801c1dac77fSApple OSS Distributions
3802c1dac77fSApple OSS Distributions /* Routine io_registry_entry_get_properties */
3803a5e72196SApple OSS Distributions kern_return_t
is_io_registry_entry_get_properties(io_object_t registry_entry,io_buf_ptr_t * properties,mach_msg_type_number_t * propertiesCnt)3804a5e72196SApple OSS Distributions is_io_registry_entry_get_properties(
3805c1dac77fSApple OSS Distributions io_object_t registry_entry,
3806c1dac77fSApple OSS Distributions io_buf_ptr_t *properties,
3807c1dac77fSApple OSS Distributions mach_msg_type_number_t *propertiesCnt )
3808c1dac77fSApple OSS Distributions {
3809a5e72196SApple OSS Distributions return kIOReturnUnsupported;
3810a3bb9fccSApple OSS Distributions }
3811a3bb9fccSApple OSS Distributions
3812a3bb9fccSApple OSS Distributions #if CONFIG_MACF
3813a3bb9fccSApple OSS Distributions
3814a5e72196SApple OSS Distributions struct GetPropertiesEditorRef {
3815a3bb9fccSApple OSS Distributions kauth_cred_t cred;
3816a3bb9fccSApple OSS Distributions IORegistryEntry * entry;
3817a3bb9fccSApple OSS Distributions OSCollection * root;
3818a3bb9fccSApple OSS Distributions };
3819a3bb9fccSApple OSS Distributions
3820e6231be0SApple OSS Distributions static const LIBKERN_RETURNS_RETAINED OSMetaClassBase *
GetPropertiesEditor(void * reference,OSSerialize * s,OSCollection * container,const OSSymbol * name,const OSMetaClassBase * value)3821a3bb9fccSApple OSS Distributions GetPropertiesEditor(void * reference,
3822a3bb9fccSApple OSS Distributions OSSerialize * s,
3823a3bb9fccSApple OSS Distributions OSCollection * container,
3824a3bb9fccSApple OSS Distributions const OSSymbol * name,
3825a3bb9fccSApple OSS Distributions const OSMetaClassBase * value)
3826a3bb9fccSApple OSS Distributions {
3827a3bb9fccSApple OSS Distributions GetPropertiesEditorRef * ref = (typeof(ref))reference;
3828a3bb9fccSApple OSS Distributions
3829a5e72196SApple OSS Distributions if (!ref->root) {
3830a5e72196SApple OSS Distributions ref->root = container;
3831a5e72196SApple OSS Distributions }
3832a5e72196SApple OSS Distributions if (ref->root == container) {
3833a5e72196SApple OSS Distributions if (0 != mac_iokit_check_get_property(ref->cred, ref->entry, name->getCStringNoCopy())) {
3834a5e72196SApple OSS Distributions value = NULL;
3835a3bb9fccSApple OSS Distributions }
3836a3bb9fccSApple OSS Distributions }
3837a5e72196SApple OSS Distributions if (value) {
3838a5e72196SApple OSS Distributions value->retain();
3839a5e72196SApple OSS Distributions }
3840a5e72196SApple OSS Distributions return value;
3841a3bb9fccSApple OSS Distributions }
3842a3bb9fccSApple OSS Distributions
3843a3bb9fccSApple OSS Distributions #endif /* CONFIG_MACF */
3844a3bb9fccSApple OSS Distributions
3845bb611c8fSApple OSS Distributions /* Routine io_registry_entry_get_properties_bin_buf */
3846a5e72196SApple OSS Distributions kern_return_t
is_io_registry_entry_get_properties_bin_buf(io_object_t registry_entry,mach_vm_address_t buf,mach_vm_size_t * bufsize,io_buf_ptr_t * properties,mach_msg_type_number_t * propertiesCnt)3847bb611c8fSApple OSS Distributions is_io_registry_entry_get_properties_bin_buf(
3848a3bb9fccSApple OSS Distributions io_object_t registry_entry,
3849bb611c8fSApple OSS Distributions mach_vm_address_t buf,
3850bb611c8fSApple OSS Distributions mach_vm_size_t *bufsize,
3851a3bb9fccSApple OSS Distributions io_buf_ptr_t *properties,
3852a3bb9fccSApple OSS Distributions mach_msg_type_number_t *propertiesCnt)
3853a3bb9fccSApple OSS Distributions {
3854a3bb9fccSApple OSS Distributions kern_return_t err = kIOReturnSuccess;
3855bb611c8fSApple OSS Distributions unsigned int len;
3856bb611c8fSApple OSS Distributions OSObject * compatProperties;
3857a3bb9fccSApple OSS Distributions OSSerialize * s;
3858a5e72196SApple OSS Distributions OSSerialize::Editor editor = NULL;
3859a5e72196SApple OSS Distributions void * editRef = NULL;
3860a3bb9fccSApple OSS Distributions
3861a3bb9fccSApple OSS Distributions CHECK(IORegistryEntry, registry_entry, entry);
3862a3bb9fccSApple OSS Distributions
3863a3bb9fccSApple OSS Distributions #if CONFIG_MACF
3864a3bb9fccSApple OSS Distributions GetPropertiesEditorRef ref;
3865a5e72196SApple OSS Distributions if (mac_iokit_check_filter_properties(kauth_cred_get(), entry)) {
3866a3bb9fccSApple OSS Distributions editor = &GetPropertiesEditor;
3867a3bb9fccSApple OSS Distributions editRef = &ref;
3868a3bb9fccSApple OSS Distributions ref.cred = kauth_cred_get();
3869a3bb9fccSApple OSS Distributions ref.entry = entry;
3870a5e72196SApple OSS Distributions ref.root = NULL;
3871a3bb9fccSApple OSS Distributions }
3872a3bb9fccSApple OSS Distributions #endif
3873a3bb9fccSApple OSS Distributions
3874a3bb9fccSApple OSS Distributions s = OSSerialize::binaryWithCapacity(4096, editor, editRef);
3875a5e72196SApple OSS Distributions if (!s) {
3876a5e72196SApple OSS Distributions return kIOReturnNoMemory;
3877a5e72196SApple OSS Distributions }
3878a3bb9fccSApple OSS Distributions
3879e6231be0SApple OSS Distributions
3880e6231be0SApple OSS Distributions compatProperties = entry->copyProperty(gIOUserServicePropertiesKey);
3881e6231be0SApple OSS Distributions if (!compatProperties
3882e6231be0SApple OSS Distributions && IOTaskRegistryCompatibility(current_task())) {
3883e6231be0SApple OSS Distributions compatProperties = entry->copyProperty(gIOCompatibilityPropertiesKey);
3884e6231be0SApple OSS Distributions }
3885e6231be0SApple OSS Distributions
3886e6231be0SApple OSS Distributions if (compatProperties) {
3887bb611c8fSApple OSS Distributions OSDictionary * dict;
3888bb611c8fSApple OSS Distributions
3889bb611c8fSApple OSS Distributions dict = entry->dictionaryWithProperties();
3890bb611c8fSApple OSS Distributions if (!dict) {
3891bb611c8fSApple OSS Distributions err = kIOReturnNoMemory;
3892bb611c8fSApple OSS Distributions } else {
3893e6231be0SApple OSS Distributions dict->removeObject(gIOUserServicePropertiesKey);
3894bb611c8fSApple OSS Distributions dict->removeObject(gIOCompatibilityPropertiesKey);
3895bb611c8fSApple OSS Distributions dict->merge(OSDynamicCast(OSDictionary, compatProperties));
3896bb611c8fSApple OSS Distributions if (!dict->serialize(s)) {
3897bb611c8fSApple OSS Distributions err = kIOReturnUnsupported;
3898bb611c8fSApple OSS Distributions }
3899bb611c8fSApple OSS Distributions dict->release();
3900bb611c8fSApple OSS Distributions }
3901bb611c8fSApple OSS Distributions compatProperties->release();
3902bb611c8fSApple OSS Distributions } else if (!entry->serializeProperties(s)) {
3903a5e72196SApple OSS Distributions err = kIOReturnUnsupported;
3904a5e72196SApple OSS Distributions }
3905a3bb9fccSApple OSS Distributions
3906a5e72196SApple OSS Distributions if (kIOReturnSuccess == err) {
3907a3bb9fccSApple OSS Distributions len = s->getLength();
3908bb611c8fSApple OSS Distributions if (buf && bufsize && len <= *bufsize) {
3909bb611c8fSApple OSS Distributions *bufsize = len;
3910bb611c8fSApple OSS Distributions *propertiesCnt = 0;
3911bb611c8fSApple OSS Distributions *properties = nullptr;
3912bb611c8fSApple OSS Distributions if (copyout(s->text(), buf, len)) {
3913bb611c8fSApple OSS Distributions err = kIOReturnVMError;
3914bb611c8fSApple OSS Distributions } else {
3915bb611c8fSApple OSS Distributions err = kIOReturnSuccess;
3916bb611c8fSApple OSS Distributions }
3917bb611c8fSApple OSS Distributions } else {
3918bb611c8fSApple OSS Distributions if (bufsize) {
3919bb611c8fSApple OSS Distributions *bufsize = 0;
3920bb611c8fSApple OSS Distributions }
3921a3bb9fccSApple OSS Distributions *propertiesCnt = len;
3922a3bb9fccSApple OSS Distributions err = copyoutkdata( s->text(), len, properties );
3923a3bb9fccSApple OSS Distributions }
3924bb611c8fSApple OSS Distributions }
3925a3bb9fccSApple OSS Distributions s->release();
3926a3bb9fccSApple OSS Distributions
3927a5e72196SApple OSS Distributions return err;
3928a3bb9fccSApple OSS Distributions }
3929a3bb9fccSApple OSS Distributions
3930bb611c8fSApple OSS Distributions /* Routine io_registry_entry_get_properties_bin */
3931a5e72196SApple OSS Distributions kern_return_t
is_io_registry_entry_get_properties_bin(io_object_t registry_entry,io_buf_ptr_t * properties,mach_msg_type_number_t * propertiesCnt)3932bb611c8fSApple OSS Distributions is_io_registry_entry_get_properties_bin(
3933bb611c8fSApple OSS Distributions io_object_t registry_entry,
3934bb611c8fSApple OSS Distributions io_buf_ptr_t *properties,
3935bb611c8fSApple OSS Distributions mach_msg_type_number_t *propertiesCnt)
3936bb611c8fSApple OSS Distributions {
3937bb611c8fSApple OSS Distributions return is_io_registry_entry_get_properties_bin_buf(registry_entry,
3938bb611c8fSApple OSS Distributions 0, NULL, properties, propertiesCnt);
3939bb611c8fSApple OSS Distributions }
3940bb611c8fSApple OSS Distributions
3941bb611c8fSApple OSS Distributions /* Routine io_registry_entry_get_property_bin_buf */
3942bb611c8fSApple OSS Distributions kern_return_t
is_io_registry_entry_get_property_bin_buf(io_object_t registry_entry,io_name_t plane,io_name_t property_name,uint32_t options,mach_vm_address_t buf,mach_vm_size_t * bufsize,io_buf_ptr_t * properties,mach_msg_type_number_t * propertiesCnt)3943bb611c8fSApple OSS Distributions is_io_registry_entry_get_property_bin_buf(
3944a3bb9fccSApple OSS Distributions io_object_t registry_entry,
3945a3bb9fccSApple OSS Distributions io_name_t plane,
3946a3bb9fccSApple OSS Distributions io_name_t property_name,
3947a3bb9fccSApple OSS Distributions uint32_t options,
3948bb611c8fSApple OSS Distributions mach_vm_address_t buf,
3949bb611c8fSApple OSS Distributions mach_vm_size_t *bufsize,
3950a3bb9fccSApple OSS Distributions io_buf_ptr_t *properties,
3951a3bb9fccSApple OSS Distributions mach_msg_type_number_t *propertiesCnt )
3952a3bb9fccSApple OSS Distributions {
3953a3bb9fccSApple OSS Distributions kern_return_t err;
3954bb611c8fSApple OSS Distributions unsigned int len;
3955a3bb9fccSApple OSS Distributions OSObject * obj;
3956a3bb9fccSApple OSS Distributions const OSSymbol * sym;
3957a3bb9fccSApple OSS Distributions
3958a3bb9fccSApple OSS Distributions CHECK( IORegistryEntry, registry_entry, entry );
3959a3bb9fccSApple OSS Distributions
3960a3bb9fccSApple OSS Distributions #if CONFIG_MACF
3961a5e72196SApple OSS Distributions if (0 != mac_iokit_check_get_property(kauth_cred_get(), entry, property_name)) {
3962a3bb9fccSApple OSS Distributions return kIOReturnNotPermitted;
3963a5e72196SApple OSS Distributions }
3964a3bb9fccSApple OSS Distributions #endif
3965a3bb9fccSApple OSS Distributions
396688cc0b97SApple OSS Distributions sym = OSSymbol::withCString(property_name);
3967a5e72196SApple OSS Distributions if (!sym) {
3968a5e72196SApple OSS Distributions return kIOReturnNoMemory;
396988cc0b97SApple OSS Distributions }
3970a5e72196SApple OSS Distributions
3971e6231be0SApple OSS Distributions err = kIOReturnNotFound;
3972a5e72196SApple OSS Distributions if (gIORegistryEntryPropertyKeysKey == sym) {
3973a5e72196SApple OSS Distributions obj = entry->copyPropertyKeys();
3974a5e72196SApple OSS Distributions } else {
3975a5e72196SApple OSS Distributions if ((kIORegistryIterateRecursively & options) && plane[0]) {
3976bb611c8fSApple OSS Distributions obj = IOCopyPropertyCompatible(entry, property_name);
3977e6231be0SApple OSS Distributions if (obj == NULL) {
3978e6231be0SApple OSS Distributions IORegistryIterator * iter = IORegistryIterator::iterateOver(entry, IORegistryEntry::getPlane(plane), options);
3979bb611c8fSApple OSS Distributions if (iter) {
3980bb611c8fSApple OSS Distributions while ((NULL == obj) && (entry = iter->getNextObject())) {
3981e6231be0SApple OSS Distributions OSObject * currentObj = IOCopyPropertyCompatible(entry, property_name);
3982e6231be0SApple OSS Distributions #if CONFIG_MACF
3983e6231be0SApple OSS Distributions if (currentObj != NULL && 0 != mac_iokit_check_get_property(kauth_cred_get(), entry, property_name)) {
3984e6231be0SApple OSS Distributions // Record that MAC hook blocked this entry and property, and continue to next entry
3985e6231be0SApple OSS Distributions err = kIOReturnNotPermitted;
3986e6231be0SApple OSS Distributions OSSafeReleaseNULL(currentObj);
3987e6231be0SApple OSS Distributions continue;
3988e6231be0SApple OSS Distributions }
3989e6231be0SApple OSS Distributions #endif
3990e6231be0SApple OSS Distributions obj = currentObj;
3991bb611c8fSApple OSS Distributions }
3992bb611c8fSApple OSS Distributions iter->release();
3993bb611c8fSApple OSS Distributions }
3994bb611c8fSApple OSS Distributions }
3995bb611c8fSApple OSS Distributions } else {
3996bb611c8fSApple OSS Distributions obj = IOCopyPropertyCompatible(entry, property_name);
3997a3bb9fccSApple OSS Distributions }
3998a5e72196SApple OSS Distributions if (obj && gIORemoveOnReadProperties->containsObject(sym)) {
3999a5e72196SApple OSS Distributions entry->removeProperty(sym);
4000a5e72196SApple OSS Distributions }
4001a3bb9fccSApple OSS Distributions }
4002a3bb9fccSApple OSS Distributions
400388cc0b97SApple OSS Distributions sym->release();
4004a5e72196SApple OSS Distributions if (!obj) {
4005e6231be0SApple OSS Distributions return err;
4006a5e72196SApple OSS Distributions }
400788cc0b97SApple OSS Distributions
4008a3bb9fccSApple OSS Distributions OSSerialize * s = OSSerialize::binaryWithCapacity(4096);
4009a3bb9fccSApple OSS Distributions if (!s) {
4010a3bb9fccSApple OSS Distributions obj->release();
4011a5e72196SApple OSS Distributions return kIOReturnNoMemory;
4012a3bb9fccSApple OSS Distributions }
4013a3bb9fccSApple OSS Distributions
4014a3bb9fccSApple OSS Distributions if (obj->serialize( s )) {
4015c1dac77fSApple OSS Distributions len = s->getLength();
4016bb611c8fSApple OSS Distributions if (buf && bufsize && len <= *bufsize) {
4017bb611c8fSApple OSS Distributions *bufsize = len;
4018bb611c8fSApple OSS Distributions *propertiesCnt = 0;
4019bb611c8fSApple OSS Distributions *properties = nullptr;
4020bb611c8fSApple OSS Distributions if (copyout(s->text(), buf, len)) {
4021bb611c8fSApple OSS Distributions err = kIOReturnVMError;
4022bb611c8fSApple OSS Distributions } else {
4023bb611c8fSApple OSS Distributions err = kIOReturnSuccess;
4024bb611c8fSApple OSS Distributions }
4025bb611c8fSApple OSS Distributions } else {
4026bb611c8fSApple OSS Distributions if (bufsize) {
4027bb611c8fSApple OSS Distributions *bufsize = 0;
4028bb611c8fSApple OSS Distributions }
4029c1dac77fSApple OSS Distributions *propertiesCnt = len;
4030c1dac77fSApple OSS Distributions err = copyoutkdata( s->text(), len, properties );
4031bb611c8fSApple OSS Distributions }
4032a5e72196SApple OSS Distributions } else {
4033a5e72196SApple OSS Distributions err = kIOReturnUnsupported;
4034a5e72196SApple OSS Distributions }
4035c1dac77fSApple OSS Distributions
4036c1dac77fSApple OSS Distributions s->release();
4037a3bb9fccSApple OSS Distributions obj->release();
4038c1dac77fSApple OSS Distributions
4039a5e72196SApple OSS Distributions return err;
4040c1dac77fSApple OSS Distributions }
4041c1dac77fSApple OSS Distributions
4042bb611c8fSApple OSS Distributions /* Routine io_registry_entry_get_property_bin */
4043bb611c8fSApple OSS Distributions kern_return_t
is_io_registry_entry_get_property_bin(io_object_t registry_entry,io_name_t plane,io_name_t property_name,uint32_t options,io_buf_ptr_t * properties,mach_msg_type_number_t * propertiesCnt)4044bb611c8fSApple OSS Distributions is_io_registry_entry_get_property_bin(
4045bb611c8fSApple OSS Distributions io_object_t registry_entry,
4046bb611c8fSApple OSS Distributions io_name_t plane,
4047bb611c8fSApple OSS Distributions io_name_t property_name,
4048bb611c8fSApple OSS Distributions uint32_t options,
4049bb611c8fSApple OSS Distributions io_buf_ptr_t *properties,
4050bb611c8fSApple OSS Distributions mach_msg_type_number_t *propertiesCnt )
4051bb611c8fSApple OSS Distributions {
4052bb611c8fSApple OSS Distributions return is_io_registry_entry_get_property_bin_buf(registry_entry, plane,
4053bb611c8fSApple OSS Distributions property_name, options, 0, NULL, properties, propertiesCnt);
4054bb611c8fSApple OSS Distributions }
4055bb611c8fSApple OSS Distributions
40560f3703acSApple OSS Distributions
4057c1dac77fSApple OSS Distributions /* Routine io_registry_entry_set_properties */
4058a5e72196SApple OSS Distributions kern_return_t
is_io_registry_entry_set_properties(io_object_t registry_entry,io_buf_ptr_t properties,mach_msg_type_number_t propertiesCnt,kern_return_t * result)4059a5e72196SApple OSS Distributions is_io_registry_entry_set_properties
4060c1dac77fSApple OSS Distributions (
4061c1dac77fSApple OSS Distributions io_object_t registry_entry,
4062c1dac77fSApple OSS Distributions io_buf_ptr_t properties,
4063c1dac77fSApple OSS Distributions mach_msg_type_number_t propertiesCnt,
4064e13b1fa5SApple OSS Distributions kern_return_t * result)
4065c1dac77fSApple OSS Distributions {
4066c1dac77fSApple OSS Distributions OSObject * obj;
4067c1dac77fSApple OSS Distributions kern_return_t err;
4068c1dac77fSApple OSS Distributions IOReturn res;
4069c1dac77fSApple OSS Distributions vm_offset_t data;
407014e3d835SApple OSS Distributions vm_map_offset_t map_data;
4071c1dac77fSApple OSS Distributions
4072c1dac77fSApple OSS Distributions CHECK( IORegistryEntry, registry_entry, entry );
4073c1dac77fSApple OSS Distributions
4074a5e72196SApple OSS Distributions if (propertiesCnt > sizeof(io_struct_inband_t) * 1024) {
4075a5e72196SApple OSS Distributions return kIOReturnMessageTooLarge;
4076a5e72196SApple OSS Distributions }
4077186b8fceSApple OSS Distributions
407814e3d835SApple OSS Distributions err = vm_map_copyout( kernel_map, &map_data, (vm_map_copy_t) properties );
407914e3d835SApple OSS Distributions data = CAST_DOWN(vm_offset_t, map_data);
4080c1dac77fSApple OSS Distributions
4081c1dac77fSApple OSS Distributions if (KERN_SUCCESS == err) {
408288cc0b97SApple OSS Distributions FAKE_STACK_FRAME(entry->getMetaClass());
408388cc0b97SApple OSS Distributions
4084c1dac77fSApple OSS Distributions // must return success after vm_map_copyout() succeeds
4085186b8fceSApple OSS Distributions obj = OSUnserializeXML((const char *) data, propertiesCnt );
4086c1dac77fSApple OSS Distributions vm_deallocate( kernel_map, data, propertiesCnt );
4087c1dac77fSApple OSS Distributions
4088a5e72196SApple OSS Distributions if (!obj) {
4089c1dac77fSApple OSS Distributions res = kIOReturnBadArgument;
4090a5e72196SApple OSS Distributions }
4091855239e5SApple OSS Distributions #if CONFIG_MACF
4092855239e5SApple OSS Distributions else if (0 != mac_iokit_check_set_properties(kauth_cred_get(),
4093a5e72196SApple OSS Distributions registry_entry, obj)) {
4094855239e5SApple OSS Distributions res = kIOReturnNotPermitted;
4095a3bb9fccSApple OSS Distributions }
4096855239e5SApple OSS Distributions #endif
4097a5e72196SApple OSS Distributions else {
4098e6231be0SApple OSS Distributions IOService * service = OSDynamicCast(IOService, entry);
4099e6231be0SApple OSS Distributions OSDictionary * props = OSDynamicCast(OSDictionary, obj);
41005c2921b0SApple OSS Distributions OSObject * allowable = entry->copyProperty(gIORegistryEntryAllowableSetPropertiesKey);
41015c2921b0SApple OSS Distributions OSArray * allowableArray;
41025c2921b0SApple OSS Distributions
41035c2921b0SApple OSS Distributions if (!allowable) {
41045c2921b0SApple OSS Distributions res = kIOReturnSuccess;
41055c2921b0SApple OSS Distributions } else {
41065c2921b0SApple OSS Distributions if (!props) {
41075c2921b0SApple OSS Distributions res = kIOReturnNotPermitted;
41085c2921b0SApple OSS Distributions } else if (!(allowableArray = OSDynamicCast(OSArray, allowable))) {
41095c2921b0SApple OSS Distributions res = kIOReturnNotPermitted;
41105c2921b0SApple OSS Distributions } else {
41115c2921b0SApple OSS Distributions bool allFound __block, found __block;
41125c2921b0SApple OSS Distributions
41135c2921b0SApple OSS Distributions allFound = true;
41145c2921b0SApple OSS Distributions props->iterateObjects(^(const OSSymbol * key, OSObject * value) {
41155c2921b0SApple OSS Distributions found = false;
41165c2921b0SApple OSS Distributions for (unsigned int idx = 0; !found; idx++) {
41175c2921b0SApple OSS Distributions OSObject * next = allowableArray->getObject(idx);
41185c2921b0SApple OSS Distributions if (!next) {
41195c2921b0SApple OSS Distributions break;
41205c2921b0SApple OSS Distributions }
41215c2921b0SApple OSS Distributions found = next->isEqualTo(key);
41225c2921b0SApple OSS Distributions }
41235c2921b0SApple OSS Distributions allFound &= found;
41245c2921b0SApple OSS Distributions if (!found) {
41255c2921b0SApple OSS Distributions IOLog("IORegistryEntrySetProperties(%s, %s) disallowed due to " kIORegistryEntryAllowableSetPropertiesKey "\n",
41265c2921b0SApple OSS Distributions entry->getName(), key->getCStringNoCopy());
41275c2921b0SApple OSS Distributions }
41285c2921b0SApple OSS Distributions return !allFound;
41295c2921b0SApple OSS Distributions });
41305c2921b0SApple OSS Distributions res = allFound ? kIOReturnSuccess : kIOReturnBadArgument;
41315c2921b0SApple OSS Distributions }
41325c2921b0SApple OSS Distributions }
41335c2921b0SApple OSS Distributions if (kIOReturnSuccess == res) {
41345c2921b0SApple OSS Distributions IOUserClient *
41355c2921b0SApple OSS Distributions client = OSDynamicCast(IOUserClient, entry);
41365c2921b0SApple OSS Distributions
41375c2921b0SApple OSS Distributions if (client && client->defaultLockingSetProperties) {
4138aca3beaaSApple OSS Distributions IORWLockWrite(&client->lock);
41395c2921b0SApple OSS Distributions }
41405c2921b0SApple OSS Distributions
41415c2921b0SApple OSS Distributions if (!client && (kOSBooleanTrue == entry->getProperty(gIORegistryEntryDefaultLockingSetPropertiesKey))) {
41425c2921b0SApple OSS Distributions res = entry->runPropertyActionBlock(^IOReturn (void) {
41435c2921b0SApple OSS Distributions return entry->setProperties( obj );
41445c2921b0SApple OSS Distributions });
41455c2921b0SApple OSS Distributions } else {
41465c2921b0SApple OSS Distributions res = entry->setProperties( obj );
41475c2921b0SApple OSS Distributions }
41485c2921b0SApple OSS Distributions
41495c2921b0SApple OSS Distributions if (client && client->defaultLockingSetProperties) {
4150aca3beaaSApple OSS Distributions IORWLockUnlock(&client->lock);
41515c2921b0SApple OSS Distributions }
4152e6231be0SApple OSS Distributions if (service && props && service->hasUserServer()) {
4153e6231be0SApple OSS Distributions res = service->UserSetProperties(props);
4154e6231be0SApple OSS Distributions }
4155a3bb9fccSApple OSS Distributions }
41565c2921b0SApple OSS Distributions OSSafeReleaseNULL(allowable);
41575c2921b0SApple OSS Distributions }
4158a5e72196SApple OSS Distributions if (obj) {
4159855239e5SApple OSS Distributions obj->release();
4160a5e72196SApple OSS Distributions }
416188cc0b97SApple OSS Distributions
416288cc0b97SApple OSS Distributions FAKE_STACK_FRAME_END();
4163a5e72196SApple OSS Distributions } else {
4164c1dac77fSApple OSS Distributions res = err;
4165a5e72196SApple OSS Distributions }
4166c1dac77fSApple OSS Distributions
4167c1dac77fSApple OSS Distributions *result = res;
4168a5e72196SApple OSS Distributions return err;
4169c1dac77fSApple OSS Distributions }
4170c1dac77fSApple OSS Distributions
4171c1dac77fSApple OSS Distributions /* Routine io_registry_entry_get_child_iterator */
4172a5e72196SApple OSS Distributions kern_return_t
is_io_registry_entry_get_child_iterator(io_object_t registry_entry,io_name_t plane,io_object_t * iterator)4173a5e72196SApple OSS Distributions is_io_registry_entry_get_child_iterator(
4174c1dac77fSApple OSS Distributions io_object_t registry_entry,
4175c1dac77fSApple OSS Distributions io_name_t plane,
4176c1dac77fSApple OSS Distributions io_object_t *iterator )
4177c1dac77fSApple OSS Distributions {
4178c1dac77fSApple OSS Distributions CHECK( IORegistryEntry, registry_entry, entry );
4179c1dac77fSApple OSS Distributions
4180cc9a6355SApple OSS Distributions *iterator = IOUserIterator::withIterator(entry->getChildIterator(
4181cc9a6355SApple OSS Distributions IORegistryEntry::getPlane( plane )));
4182c1dac77fSApple OSS Distributions
4183a5e72196SApple OSS Distributions return kIOReturnSuccess;
4184c1dac77fSApple OSS Distributions }
4185c1dac77fSApple OSS Distributions
4186c1dac77fSApple OSS Distributions /* Routine io_registry_entry_get_parent_iterator */
4187a5e72196SApple OSS Distributions kern_return_t
is_io_registry_entry_get_parent_iterator(io_object_t registry_entry,io_name_t plane,io_object_t * iterator)4188a5e72196SApple OSS Distributions is_io_registry_entry_get_parent_iterator(
4189c1dac77fSApple OSS Distributions io_object_t registry_entry,
4190c1dac77fSApple OSS Distributions io_name_t plane,
4191c1dac77fSApple OSS Distributions io_object_t *iterator)
4192c1dac77fSApple OSS Distributions {
4193c1dac77fSApple OSS Distributions CHECK( IORegistryEntry, registry_entry, entry );
4194c1dac77fSApple OSS Distributions
4195cc9a6355SApple OSS Distributions *iterator = IOUserIterator::withIterator(entry->getParentIterator(
4196cc9a6355SApple OSS Distributions IORegistryEntry::getPlane( plane )));
4197c1dac77fSApple OSS Distributions
4198a5e72196SApple OSS Distributions return kIOReturnSuccess;
4199c1dac77fSApple OSS Distributions }
4200c1dac77fSApple OSS Distributions
4201c1dac77fSApple OSS Distributions /* Routine io_service_get_busy_state */
4202a5e72196SApple OSS Distributions kern_return_t
is_io_service_get_busy_state(io_object_t _service,uint32_t * busyState)4203a5e72196SApple OSS Distributions is_io_service_get_busy_state(
4204c1dac77fSApple OSS Distributions io_object_t _service,
4205e13b1fa5SApple OSS Distributions uint32_t *busyState )
4206c1dac77fSApple OSS Distributions {
4207c1dac77fSApple OSS Distributions CHECK( IOService, _service, service );
4208c1dac77fSApple OSS Distributions
4209c1dac77fSApple OSS Distributions *busyState = service->getBusyState();
4210c1dac77fSApple OSS Distributions
4211a5e72196SApple OSS Distributions return kIOReturnSuccess;
4212c1dac77fSApple OSS Distributions }
4213c1dac77fSApple OSS Distributions
4214368ad365SApple OSS Distributions /* Routine io_service_get_state */
4215a5e72196SApple OSS Distributions kern_return_t
is_io_service_get_state(io_object_t _service,uint64_t * state,uint32_t * busy_state,uint64_t * accumulated_busy_time)4216a5e72196SApple OSS Distributions is_io_service_get_state(
4217368ad365SApple OSS Distributions io_object_t _service,
42183ca3bd55SApple OSS Distributions uint64_t *state,
42193ca3bd55SApple OSS Distributions uint32_t *busy_state,
42203ca3bd55SApple OSS Distributions uint64_t *accumulated_busy_time )
4221368ad365SApple OSS Distributions {
4222368ad365SApple OSS Distributions CHECK( IOService, _service, service );
4223368ad365SApple OSS Distributions
4224368ad365SApple OSS Distributions *state = service->getState();
42253ca3bd55SApple OSS Distributions *busy_state = service->getBusyState();
42263ca3bd55SApple OSS Distributions *accumulated_busy_time = service->getAccumulatedBusyTime();
4227368ad365SApple OSS Distributions
4228a5e72196SApple OSS Distributions return kIOReturnSuccess;
4229368ad365SApple OSS Distributions }
4230368ad365SApple OSS Distributions
4231c1dac77fSApple OSS Distributions /* Routine io_service_wait_quiet */
4232a5e72196SApple OSS Distributions kern_return_t
is_io_service_wait_quiet(io_object_t _service,mach_timespec_t wait_time)4233a5e72196SApple OSS Distributions is_io_service_wait_quiet(
4234c1dac77fSApple OSS Distributions io_object_t _service,
4235c1dac77fSApple OSS Distributions mach_timespec_t wait_time )
4236c1dac77fSApple OSS Distributions {
42373ca3bd55SApple OSS Distributions uint64_t timeoutNS;
42383ca3bd55SApple OSS Distributions
4239c1dac77fSApple OSS Distributions CHECK( IOService, _service, service );
4240c1dac77fSApple OSS Distributions
42413ca3bd55SApple OSS Distributions timeoutNS = wait_time.tv_sec;
42423ca3bd55SApple OSS Distributions timeoutNS *= kSecondScale;
42433ca3bd55SApple OSS Distributions timeoutNS += wait_time.tv_nsec;
42443ca3bd55SApple OSS Distributions
4245a5e72196SApple OSS Distributions return service->waitQuiet(timeoutNS);
4246c1dac77fSApple OSS Distributions }
4247c1dac77fSApple OSS Distributions
42485c2921b0SApple OSS Distributions /* Routine io_service_wait_quiet_with_options */
42495c2921b0SApple OSS Distributions kern_return_t
is_io_service_wait_quiet_with_options(io_object_t _service,mach_timespec_t wait_time,uint32_t options)42505c2921b0SApple OSS Distributions is_io_service_wait_quiet_with_options(
42515c2921b0SApple OSS Distributions io_object_t _service,
42525c2921b0SApple OSS Distributions mach_timespec_t wait_time,
42535c2921b0SApple OSS Distributions uint32_t options )
42545c2921b0SApple OSS Distributions {
42555c2921b0SApple OSS Distributions uint64_t timeoutNS;
42565c2921b0SApple OSS Distributions
42575c2921b0SApple OSS Distributions CHECK( IOService, _service, service );
42585c2921b0SApple OSS Distributions
42595c2921b0SApple OSS Distributions timeoutNS = wait_time.tv_sec;
42605c2921b0SApple OSS Distributions timeoutNS *= kSecondScale;
42615c2921b0SApple OSS Distributions timeoutNS += wait_time.tv_nsec;
42625c2921b0SApple OSS Distributions
42635c2921b0SApple OSS Distributions if ((options & kIOWaitQuietPanicOnFailure) && !IOCurrentTaskHasEntitlement(kIOWaitQuietPanicsEntitlement)) {
42645c2921b0SApple OSS Distributions OSString * taskName = IOCopyLogNameForPID(proc_selfpid());
42655c2921b0SApple OSS Distributions IOLog("IOServiceWaitQuietWithOptions(%s): Not entitled\n", taskName ? taskName->getCStringNoCopy() : "");
42665c2921b0SApple OSS Distributions OSSafeReleaseNULL(taskName);
42675c2921b0SApple OSS Distributions
42685c2921b0SApple OSS Distributions /* strip this option from the options before calling waitQuietWithOptions */
42695c2921b0SApple OSS Distributions options &= ~kIOWaitQuietPanicOnFailure;
42705c2921b0SApple OSS Distributions }
42715c2921b0SApple OSS Distributions
42725c2921b0SApple OSS Distributions return service->waitQuietWithOptions(timeoutNS, options);
42735c2921b0SApple OSS Distributions }
42745c2921b0SApple OSS Distributions
42755c2921b0SApple OSS Distributions
4276c1dac77fSApple OSS Distributions /* Routine io_service_request_probe */
4277a5e72196SApple OSS Distributions kern_return_t
is_io_service_request_probe(io_object_t _service,uint32_t options)4278a5e72196SApple OSS Distributions is_io_service_request_probe(
4279c1dac77fSApple OSS Distributions io_object_t _service,
4280e13b1fa5SApple OSS Distributions uint32_t options )
4281c1dac77fSApple OSS Distributions {
4282c1dac77fSApple OSS Distributions CHECK( IOService, _service, service );
4283c1dac77fSApple OSS Distributions
4284a5e72196SApple OSS Distributions return service->requestProbe( options );
4285c1dac77fSApple OSS Distributions }
4286c1dac77fSApple OSS Distributions
4287a3bb9fccSApple OSS Distributions /* Routine io_service_get_authorization_id */
4288a5e72196SApple OSS Distributions kern_return_t
is_io_service_get_authorization_id(io_object_t _service,uint64_t * authorization_id)4289a5e72196SApple OSS Distributions is_io_service_get_authorization_id(
4290a3bb9fccSApple OSS Distributions io_object_t _service,
4291a3bb9fccSApple OSS Distributions uint64_t *authorization_id )
4292a3bb9fccSApple OSS Distributions {
4293a3bb9fccSApple OSS Distributions kern_return_t kr;
4294a3bb9fccSApple OSS Distributions
4295a3bb9fccSApple OSS Distributions CHECK( IOService, _service, service );
4296a3bb9fccSApple OSS Distributions
4297a3bb9fccSApple OSS Distributions kr = IOUserClient::clientHasPrivilege((void *) current_task(),
4298a3bb9fccSApple OSS Distributions kIOClientPrivilegeAdministrator );
4299a5e72196SApple OSS Distributions if (kIOReturnSuccess != kr) {
4300a5e72196SApple OSS Distributions return kr;
4301a5e72196SApple OSS Distributions }
4302a3bb9fccSApple OSS Distributions
43031031c584SApple OSS Distributions #if defined(XNU_TARGET_OS_OSX)
4304a3bb9fccSApple OSS Distributions *authorization_id = service->getAuthorizationID();
43051031c584SApple OSS Distributions #else /* defined(XNU_TARGET_OS_OSX) */
43061031c584SApple OSS Distributions *authorization_id = 0;
43071031c584SApple OSS Distributions kr = kIOReturnUnsupported;
43081031c584SApple OSS Distributions #endif /* defined(XNU_TARGET_OS_OSX) */
4309a3bb9fccSApple OSS Distributions
4310a5e72196SApple OSS Distributions return kr;
4311a3bb9fccSApple OSS Distributions }
4312a3bb9fccSApple OSS Distributions
4313a3bb9fccSApple OSS Distributions /* Routine io_service_set_authorization_id */
4314a5e72196SApple OSS Distributions kern_return_t
is_io_service_set_authorization_id(io_object_t _service,uint64_t authorization_id)4315a5e72196SApple OSS Distributions is_io_service_set_authorization_id(
4316a3bb9fccSApple OSS Distributions io_object_t _service,
4317a3bb9fccSApple OSS Distributions uint64_t authorization_id )
4318a3bb9fccSApple OSS Distributions {
4319a3bb9fccSApple OSS Distributions CHECK( IOService, _service, service );
4320a3bb9fccSApple OSS Distributions
43211031c584SApple OSS Distributions #if defined(XNU_TARGET_OS_OSX)
4322a5e72196SApple OSS Distributions return service->setAuthorizationID( authorization_id );
43231031c584SApple OSS Distributions #else /* defined(XNU_TARGET_OS_OSX) */
43241031c584SApple OSS Distributions return kIOReturnUnsupported;
43251031c584SApple OSS Distributions #endif /* defined(XNU_TARGET_OS_OSX) */
4326a3bb9fccSApple OSS Distributions }
4327a3bb9fccSApple OSS Distributions
4328e13b1fa5SApple OSS Distributions /* Routine io_service_open_ndr */
4329a5e72196SApple OSS Distributions kern_return_t
is_io_service_open_extended(io_object_t _service,task_t owningTask,uint32_t connect_type,NDR_record_t ndr,io_buf_ptr_t properties,mach_msg_type_number_t propertiesCnt,kern_return_t * result,io_object_t * connection)4330a5e72196SApple OSS Distributions is_io_service_open_extended(
4331e13b1fa5SApple OSS Distributions io_object_t _service,
4332e13b1fa5SApple OSS Distributions task_t owningTask,
4333e13b1fa5SApple OSS Distributions uint32_t connect_type,
4334e13b1fa5SApple OSS Distributions NDR_record_t ndr,
4335e13b1fa5SApple OSS Distributions io_buf_ptr_t properties,
4336e13b1fa5SApple OSS Distributions mach_msg_type_number_t propertiesCnt,
4337e13b1fa5SApple OSS Distributions kern_return_t * result,
4338e13b1fa5SApple OSS Distributions io_object_t *connection )
4339e13b1fa5SApple OSS Distributions {
4340a5e72196SApple OSS Distributions IOUserClient * client = NULL;
4341e13b1fa5SApple OSS Distributions kern_return_t err = KERN_SUCCESS;
4342e13b1fa5SApple OSS Distributions IOReturn res = kIOReturnSuccess;
4343a5e72196SApple OSS Distributions OSDictionary * propertiesDict = NULL;
43445c2921b0SApple OSS Distributions bool disallowAccess = false;
4345e13b1fa5SApple OSS Distributions
4346e13b1fa5SApple OSS Distributions CHECK( IOService, _service, service );
4347e13b1fa5SApple OSS Distributions
4348a5e72196SApple OSS Distributions if (!owningTask) {
4349a5e72196SApple OSS Distributions return kIOReturnBadArgument;
4350a5e72196SApple OSS Distributions }
435188cc0b97SApple OSS Distributions assert(owningTask == current_task());
4352a5e72196SApple OSS Distributions if (owningTask != current_task()) {
4353a5e72196SApple OSS Distributions return kIOReturnBadArgument;
4354a5e72196SApple OSS Distributions }
43550f3703acSApple OSS Distributions
4356e6231be0SApple OSS Distributions #if CONFIG_MACF
4357e6231be0SApple OSS Distributions if (mac_iokit_check_open_service(kauth_cred_get(), service, connect_type) != 0) {
4358e6231be0SApple OSS Distributions return kIOReturnNotPermitted;
4359e6231be0SApple OSS Distributions }
4360e6231be0SApple OSS Distributions #endif
4361a5e72196SApple OSS Distributions do{
4362a5e72196SApple OSS Distributions if (properties) {
4363a5e72196SApple OSS Distributions return kIOReturnUnsupported;
4364a5e72196SApple OSS Distributions }
436576e12aa3SApple OSS Distributions #if 0
4366e13b1fa5SApple OSS Distributions {
4367e13b1fa5SApple OSS Distributions OSObject * obj;
4368e13b1fa5SApple OSS Distributions vm_offset_t data;
4369e13b1fa5SApple OSS Distributions vm_map_offset_t map_data;
4370e13b1fa5SApple OSS Distributions
4371a5e72196SApple OSS Distributions if (propertiesCnt > sizeof(io_struct_inband_t)) {
4372a5e72196SApple OSS Distributions return kIOReturnMessageTooLarge;
4373a5e72196SApple OSS Distributions }
4374186b8fceSApple OSS Distributions
4375e13b1fa5SApple OSS Distributions err = vm_map_copyout( kernel_map, &map_data, (vm_map_copy_t) properties );
4376e13b1fa5SApple OSS Distributions res = err;
4377e13b1fa5SApple OSS Distributions data = CAST_DOWN(vm_offset_t, map_data);
4378a5e72196SApple OSS Distributions if (KERN_SUCCESS == err) {
4379e13b1fa5SApple OSS Distributions // must return success after vm_map_copyout() succeeds
4380186b8fceSApple OSS Distributions obj = OSUnserializeXML((const char *) data, propertiesCnt );
4381e13b1fa5SApple OSS Distributions vm_deallocate( kernel_map, data, propertiesCnt );
4382e13b1fa5SApple OSS Distributions propertiesDict = OSDynamicCast(OSDictionary, obj);
4383a5e72196SApple OSS Distributions if (!propertiesDict) {
4384e13b1fa5SApple OSS Distributions res = kIOReturnBadArgument;
4385a5e72196SApple OSS Distributions if (obj) {
4386e13b1fa5SApple OSS Distributions obj->release();
4387e13b1fa5SApple OSS Distributions }
4388e13b1fa5SApple OSS Distributions }
4389a5e72196SApple OSS Distributions }
4390a5e72196SApple OSS Distributions if (kIOReturnSuccess != res) {
4391e13b1fa5SApple OSS Distributions break;
4392e13b1fa5SApple OSS Distributions }
4393a5e72196SApple OSS Distributions }
439476e12aa3SApple OSS Distributions #endif
4395e13b1fa5SApple OSS Distributions res = service->newUserClient( owningTask, (void *) owningTask,
4396e13b1fa5SApple OSS Distributions connect_type, propertiesDict, &client );
4397e13b1fa5SApple OSS Distributions
4398a5e72196SApple OSS Distributions if (propertiesDict) {
4399e13b1fa5SApple OSS Distributions propertiesDict->release();
4400a5e72196SApple OSS Distributions }
4401e13b1fa5SApple OSS Distributions
4402e6231be0SApple OSS Distributions if (res == kIOReturnSuccess && OSDynamicCast(IOUserClient, client) == NULL) {
4403e6231be0SApple OSS Distributions // client should always be a IOUserClient
4404e6231be0SApple OSS Distributions res = kIOReturnError;
4405e6231be0SApple OSS Distributions }
4406e6231be0SApple OSS Distributions
4407a5e72196SApple OSS Distributions if (res == kIOReturnSuccess) {
4408bb611c8fSApple OSS Distributions if (!client->reserved) {
4409bb611c8fSApple OSS Distributions if (!client->reserve()) {
4410bb611c8fSApple OSS Distributions client->clientClose();
4411bb611c8fSApple OSS Distributions OSSafeReleaseNULL(client);
4412bb611c8fSApple OSS Distributions res = kIOReturnNoMemory;
4413bb611c8fSApple OSS Distributions }
4414bb611c8fSApple OSS Distributions }
4415bb611c8fSApple OSS Distributions }
4416e13b1fa5SApple OSS Distributions
4417bb611c8fSApple OSS Distributions if (res == kIOReturnSuccess) {
44185c2921b0SApple OSS Distributions OSString * creatorName = IOCopyLogNameForPID(proc_selfpid());
44195c2921b0SApple OSS Distributions if (creatorName) {
44205c2921b0SApple OSS Distributions client->setProperty(kIOUserClientCreatorKey, creatorName);
44215c2921b0SApple OSS Distributions }
44225c2921b0SApple OSS Distributions const char * creatorNameCStr = creatorName ? creatorName->getCStringNoCopy() : "<unknown>";
4423a5e72196SApple OSS Distributions client->sharedInstance = (NULL != client->getProperty(kIOUserClientSharedInstanceKey));
4424bb611c8fSApple OSS Distributions if (client->sharedInstance) {
4425bb611c8fSApple OSS Distributions IOLockLock(gIOUserClientOwnersLock);
4426bb611c8fSApple OSS Distributions }
4427aca3beaaSApple OSS Distributions if (!client->opened) {
4428aca3beaaSApple OSS Distributions client->opened = true;
4429bb611c8fSApple OSS Distributions
4430a5e72196SApple OSS Distributions client->messageAppSuspended = (NULL != client->getProperty(kIOUserClientMessageAppSuspendedKey));
4431bb611c8fSApple OSS Distributions {
4432bb611c8fSApple OSS Distributions OSObject * obj;
4433bb611c8fSApple OSS Distributions extern const OSSymbol * gIOSurfaceIdentifier;
4434bb611c8fSApple OSS Distributions obj = client->getProperty(kIOUserClientDefaultLockingKey);
44355c2921b0SApple OSS Distributions bool hasProps = false;
44365c2921b0SApple OSS Distributions
44375c2921b0SApple OSS Distributions client->uc2022 = (NULL != OSDynamicCast(IOUserClient2022, client));
4438bb611c8fSApple OSS Distributions if (obj) {
44395c2921b0SApple OSS Distributions hasProps = true;
4440bb611c8fSApple OSS Distributions client->defaultLocking = (kOSBooleanFalse != client->getProperty(kIOUserClientDefaultLockingKey));
44415c2921b0SApple OSS Distributions } else if (client->uc2022) {
44425c2921b0SApple OSS Distributions res = kIOReturnError;
44435c2921b0SApple OSS Distributions }
44445c2921b0SApple OSS Distributions obj = client->getProperty(kIOUserClientDefaultLockingSetPropertiesKey);
44455c2921b0SApple OSS Distributions if (obj) {
44465c2921b0SApple OSS Distributions hasProps = true;
44475c2921b0SApple OSS Distributions client->defaultLockingSetProperties = (kOSBooleanFalse != client->getProperty(kIOUserClientDefaultLockingSetPropertiesKey));
44485c2921b0SApple OSS Distributions } else if (client->uc2022) {
44495c2921b0SApple OSS Distributions res = kIOReturnError;
44505c2921b0SApple OSS Distributions }
44515c2921b0SApple OSS Distributions obj = client->getProperty(kIOUserClientDefaultLockingSingleThreadExternalMethodKey);
44525c2921b0SApple OSS Distributions if (obj) {
44535c2921b0SApple OSS Distributions hasProps = true;
44545c2921b0SApple OSS Distributions client->defaultLockingSingleThreadExternalMethod = (kOSBooleanFalse != client->getProperty(kIOUserClientDefaultLockingSingleThreadExternalMethodKey));
44555c2921b0SApple OSS Distributions } else if (client->uc2022) {
44565c2921b0SApple OSS Distributions res = kIOReturnError;
44575c2921b0SApple OSS Distributions }
44585c2921b0SApple OSS Distributions if (kIOReturnSuccess != res) {
44595c2921b0SApple OSS Distributions IOLog("IOUC %s requires kIOUserClientDefaultLockingKey, kIOUserClientDefaultLockingSetPropertiesKey, kIOUserClientDefaultLockingSingleThreadExternalMethodKey\n",
44605c2921b0SApple OSS Distributions client->getMetaClass()->getClassName());
44615c2921b0SApple OSS Distributions }
44625c2921b0SApple OSS Distributions if (!hasProps) {
4463bb611c8fSApple OSS Distributions const OSMetaClass * meta;
4464bb611c8fSApple OSS Distributions OSKext * kext;
4465bb611c8fSApple OSS Distributions meta = client->getMetaClass();
4466bb611c8fSApple OSS Distributions kext = meta->getKext();
4467bb611c8fSApple OSS Distributions if (!kext || !kext->hasDependency(gIOSurfaceIdentifier)) {
4468bb611c8fSApple OSS Distributions client->defaultLocking = true;
44695c2921b0SApple OSS Distributions client->defaultLockingSetProperties = false;
44705c2921b0SApple OSS Distributions client->defaultLockingSingleThreadExternalMethod = false;
4471bb611c8fSApple OSS Distributions client->setProperty(kIOUserClientDefaultLockingKey, kOSBooleanTrue);
4472bb611c8fSApple OSS Distributions }
4473bb611c8fSApple OSS Distributions }
4474bb611c8fSApple OSS Distributions }
4475bb611c8fSApple OSS Distributions }
4476bb611c8fSApple OSS Distributions if (client->sharedInstance) {
4477bb611c8fSApple OSS Distributions IOLockUnlock(gIOUserClientOwnersLock);
4478bb611c8fSApple OSS Distributions }
447988cc0b97SApple OSS Distributions
44805c2921b0SApple OSS Distributions OSObject * requiredEntitlement = client->copyProperty(gIOUserClientEntitlementsKey);
44815c2921b0SApple OSS Distributions OSString * requiredEntitlementString = OSDynamicCast(OSString, requiredEntitlement);
44825c2921b0SApple OSS Distributions //If this is an IOUserClient2022, having kIOUserClientEntitlementsKey is mandatory.
44835c2921b0SApple OSS Distributions //If it has kIOUserClientEntitlementsKey, the value must be either kOSBooleanFalse or an OSString
44845c2921b0SApple OSS Distributions //If the value is kOSBooleanFalse, we allow access.
44855c2921b0SApple OSS Distributions //If the value is an OSString, we allow access if the task has the named entitlement
44865c2921b0SApple OSS Distributions if (client->uc2022) {
44875c2921b0SApple OSS Distributions if (!requiredEntitlement) {
44885c2921b0SApple OSS Distributions IOLog("IOUC %s missing " kIOUserClientEntitlementsKey " property\n",
44895c2921b0SApple OSS Distributions client->getMetaClass()->getClassName());
44905c2921b0SApple OSS Distributions disallowAccess = true;
44915c2921b0SApple OSS Distributions } else if (!requiredEntitlementString && requiredEntitlement != kOSBooleanFalse) {
44925c2921b0SApple OSS Distributions IOLog("IOUC %s had " kIOUserClientEntitlementsKey "with value not boolean false or string\n", client->getMetaClass()->getClassName());
44935c2921b0SApple OSS Distributions disallowAccess = true;
44945c2921b0SApple OSS Distributions }
44955c2921b0SApple OSS Distributions }
44965c2921b0SApple OSS Distributions
44975c2921b0SApple OSS Distributions if (requiredEntitlement && disallowAccess == false) {
44985c2921b0SApple OSS Distributions if (kOSBooleanFalse == requiredEntitlement) {
44995c2921b0SApple OSS Distributions // allow
45005c2921b0SApple OSS Distributions disallowAccess = false;
45015c2921b0SApple OSS Distributions } else {
45025c2921b0SApple OSS Distributions disallowAccess = !IOTaskHasEntitlement(owningTask, requiredEntitlementString->getCStringNoCopy());
4503a5e72196SApple OSS Distributions if (disallowAccess) {
45045c2921b0SApple OSS Distributions IOLog("IOUC %s missing entitlement in process %s\n",
45055c2921b0SApple OSS Distributions client->getMetaClass()->getClassName(), creatorNameCStr);
45065c2921b0SApple OSS Distributions }
45075c2921b0SApple OSS Distributions }
45085c2921b0SApple OSS Distributions }
45095c2921b0SApple OSS Distributions
45105c2921b0SApple OSS Distributions OSSafeReleaseNULL(requiredEntitlement);
45115c2921b0SApple OSS Distributions
45125c2921b0SApple OSS Distributions if (disallowAccess) {
45135c2921b0SApple OSS Distributions res = kIOReturnNotPrivileged;
4514a5e72196SApple OSS Distributions }
4515855239e5SApple OSS Distributions #if CONFIG_MACF
4516a5e72196SApple OSS Distributions else if (0 != mac_iokit_check_open(kauth_cred_get(), client, connect_type)) {
45175c2921b0SApple OSS Distributions IOLog("IOUC %s failed MACF in process %s\n",
45185c2921b0SApple OSS Distributions client->getMetaClass()->getClassName(), creatorNameCStr);
4519855239e5SApple OSS Distributions res = kIOReturnNotPermitted;
4520a5e72196SApple OSS Distributions }
4521855239e5SApple OSS Distributions #endif
452288cc0b97SApple OSS Distributions
4523bb611c8fSApple OSS Distributions if ((kIOReturnSuccess == res)
4524bb611c8fSApple OSS Distributions && gIOUCFilterCallbacks
4525bb611c8fSApple OSS Distributions && gIOUCFilterCallbacks->io_filter_resolver) {
4526bb611c8fSApple OSS Distributions io_filter_policy_t filterPolicy;
4527bb611c8fSApple OSS Distributions filterPolicy = client->filterForTask(owningTask, 0);
4528bb611c8fSApple OSS Distributions if (!filterPolicy) {
4529bb611c8fSApple OSS Distributions res = gIOUCFilterCallbacks->io_filter_resolver(owningTask, client, connect_type, &filterPolicy);
4530bb611c8fSApple OSS Distributions if (kIOReturnUnsupported == res) {
4531bb611c8fSApple OSS Distributions res = kIOReturnSuccess;
4532bb611c8fSApple OSS Distributions } else if (kIOReturnSuccess == res) {
4533bb611c8fSApple OSS Distributions client->filterForTask(owningTask, filterPolicy);
45345c2921b0SApple OSS Distributions } else {
45355c2921b0SApple OSS Distributions IOLog("IOUC %s failed sandbox in process %s\n",
45365c2921b0SApple OSS Distributions client->getMetaClass()->getClassName(), creatorNameCStr);
4537bb611c8fSApple OSS Distributions }
4538bb611c8fSApple OSS Distributions }
4539bb611c8fSApple OSS Distributions }
4540bb611c8fSApple OSS Distributions
4541a5e72196SApple OSS Distributions if (kIOReturnSuccess == res) {
4542a5e72196SApple OSS Distributions res = client->registerOwner(owningTask);
4543a5e72196SApple OSS Distributions }
45445c2921b0SApple OSS Distributions OSSafeReleaseNULL(creatorName);
454588cc0b97SApple OSS Distributions
4546a5e72196SApple OSS Distributions if (kIOReturnSuccess != res) {
4547855239e5SApple OSS Distributions IOStatisticsClientCall();
4548e13b1fa5SApple OSS Distributions client->clientClose();
45495c2921b0SApple OSS Distributions client->setTerminateDefer(service, false);
4550e13b1fa5SApple OSS Distributions client->release();
4551a5e72196SApple OSS Distributions client = NULL;
4552e13b1fa5SApple OSS Distributions break;
4553e13b1fa5SApple OSS Distributions }
4554186b8fceSApple OSS Distributions client->setTerminateDefer(service, false);
4555e13b1fa5SApple OSS Distributions }
4556a5e72196SApple OSS Distributions }while (false);
4557e13b1fa5SApple OSS Distributions
4558e13b1fa5SApple OSS Distributions *connection = client;
4559e13b1fa5SApple OSS Distributions *result = res;
4560e13b1fa5SApple OSS Distributions
4561a5e72196SApple OSS Distributions return err;
4562e13b1fa5SApple OSS Distributions }
4563e13b1fa5SApple OSS Distributions
4564c1dac77fSApple OSS Distributions /* Routine io_service_close */
4565a5e72196SApple OSS Distributions kern_return_t
is_io_service_close(io_connect_t connection)4566a5e72196SApple OSS Distributions is_io_service_close(
456794d3b452SApple OSS Distributions io_connect_t connection )
4568c1dac77fSApple OSS Distributions {
4569368ad365SApple OSS Distributions OSSet * mappings;
4570a5e72196SApple OSS Distributions if ((mappings = OSDynamicCast(OSSet, connection))) {
4571a5e72196SApple OSS Distributions return kIOReturnSuccess;
4572a5e72196SApple OSS Distributions }
4573368ad365SApple OSS Distributions
4574c1dac77fSApple OSS Distributions CHECK( IOUserClient, connection, client );
4575c1dac77fSApple OSS Distributions
4576855239e5SApple OSS Distributions IOStatisticsClientCall();
457788cc0b97SApple OSS Distributions
4578a5e72196SApple OSS Distributions if (client->sharedInstance || OSCompareAndSwap8(0, 1, &client->closed)) {
457994d3b452SApple OSS Distributions client->ipcEnter(kIPCLockWrite);
4580c1dac77fSApple OSS Distributions client->clientClose();
458194d3b452SApple OSS Distributions client->ipcExit(kIPCLockWrite);
4582a5e72196SApple OSS Distributions } else {
458388cc0b97SApple OSS Distributions IOLog("ignored is_io_service_close(0x%qx,%s)\n",
458488cc0b97SApple OSS Distributions client->getRegistryEntryID(), client->getName());
458588cc0b97SApple OSS Distributions }
4586c1dac77fSApple OSS Distributions
4587a5e72196SApple OSS Distributions return kIOReturnSuccess;
4588c1dac77fSApple OSS Distributions }
4589c1dac77fSApple OSS Distributions
4590c1dac77fSApple OSS Distributions /* Routine io_connect_get_service */
4591a5e72196SApple OSS Distributions kern_return_t
is_io_connect_get_service(io_connect_t connection,io_object_t * service)4592a5e72196SApple OSS Distributions is_io_connect_get_service(
459394d3b452SApple OSS Distributions io_connect_t connection,
4594c1dac77fSApple OSS Distributions io_object_t *service )
4595c1dac77fSApple OSS Distributions {
4596c1dac77fSApple OSS Distributions IOService * theService;
4597c1dac77fSApple OSS Distributions
4598c1dac77fSApple OSS Distributions CHECK( IOUserClient, connection, client );
4599c1dac77fSApple OSS Distributions
460094d3b452SApple OSS Distributions client->ipcEnter(kIPCLockNone);
460194d3b452SApple OSS Distributions
4602c1dac77fSApple OSS Distributions theService = client->getService();
4603a5e72196SApple OSS Distributions if (theService) {
4604c1dac77fSApple OSS Distributions theService->retain();
4605a5e72196SApple OSS Distributions }
4606c1dac77fSApple OSS Distributions
460794d3b452SApple OSS Distributions client->ipcExit(kIPCLockNone);
460894d3b452SApple OSS Distributions
4609c1dac77fSApple OSS Distributions *service = theService;
4610c1dac77fSApple OSS Distributions
4611a5e72196SApple OSS Distributions return theService ? kIOReturnSuccess : kIOReturnUnsupported;
4612c1dac77fSApple OSS Distributions }
4613c1dac77fSApple OSS Distributions
4614c1dac77fSApple OSS Distributions /* Routine io_connect_set_notification_port */
4615a5e72196SApple OSS Distributions kern_return_t
is_io_connect_set_notification_port(io_connect_t connection,uint32_t notification_type,mach_port_t port,uint32_t reference)4616a5e72196SApple OSS Distributions is_io_connect_set_notification_port(
461794d3b452SApple OSS Distributions io_connect_t connection,
4618e13b1fa5SApple OSS Distributions uint32_t notification_type,
4619c1dac77fSApple OSS Distributions mach_port_t port,
4620e13b1fa5SApple OSS Distributions uint32_t reference)
4621c1dac77fSApple OSS Distributions {
4622cc9a6355SApple OSS Distributions kern_return_t ret;
4623c1dac77fSApple OSS Distributions CHECK( IOUserClient, connection, client );
4624c1dac77fSApple OSS Distributions
4625855239e5SApple OSS Distributions IOStatisticsClientCall();
462694d3b452SApple OSS Distributions
462794d3b452SApple OSS Distributions client->ipcEnter(kIPCLockWrite);
4628cc9a6355SApple OSS Distributions ret = client->registerNotificationPort( port, notification_type,
4629cc9a6355SApple OSS Distributions (io_user_reference_t) reference );
463094d3b452SApple OSS Distributions client->ipcExit(kIPCLockWrite);
463194d3b452SApple OSS Distributions
4632a5e72196SApple OSS Distributions return ret;
4633c1dac77fSApple OSS Distributions }
4634c1dac77fSApple OSS Distributions
4635e13b1fa5SApple OSS Distributions /* Routine io_connect_set_notification_port */
4636a5e72196SApple OSS Distributions kern_return_t
is_io_connect_set_notification_port_64(io_connect_t connection,uint32_t notification_type,mach_port_t port,io_user_reference_t reference)4637a5e72196SApple OSS Distributions is_io_connect_set_notification_port_64(
463894d3b452SApple OSS Distributions io_connect_t connection,
4639e13b1fa5SApple OSS Distributions uint32_t notification_type,
4640e13b1fa5SApple OSS Distributions mach_port_t port,
4641e13b1fa5SApple OSS Distributions io_user_reference_t reference)
4642e13b1fa5SApple OSS Distributions {
4643cc9a6355SApple OSS Distributions kern_return_t ret;
4644e13b1fa5SApple OSS Distributions CHECK( IOUserClient, connection, client );
4645e13b1fa5SApple OSS Distributions
4646855239e5SApple OSS Distributions IOStatisticsClientCall();
464794d3b452SApple OSS Distributions
464894d3b452SApple OSS Distributions client->ipcEnter(kIPCLockWrite);
4649cc9a6355SApple OSS Distributions ret = client->registerNotificationPort( port, notification_type,
4650cc9a6355SApple OSS Distributions reference );
465194d3b452SApple OSS Distributions client->ipcExit(kIPCLockWrite);
465294d3b452SApple OSS Distributions
4653a5e72196SApple OSS Distributions return ret;
4654e13b1fa5SApple OSS Distributions }
4655e13b1fa5SApple OSS Distributions
4656e13b1fa5SApple OSS Distributions /* Routine io_connect_map_memory_into_task */
4657a5e72196SApple OSS Distributions kern_return_t
is_io_connect_map_memory_into_task(io_connect_t connection,uint32_t memory_type,task_t into_task,mach_vm_address_t * address,mach_vm_size_t * size,uint32_t flags)4658a5e72196SApple OSS Distributions is_io_connect_map_memory_into_task
4659e13b1fa5SApple OSS Distributions (
4660e13b1fa5SApple OSS Distributions io_connect_t connection,
4661e13b1fa5SApple OSS Distributions uint32_t memory_type,
4662e13b1fa5SApple OSS Distributions task_t into_task,
4663e13b1fa5SApple OSS Distributions mach_vm_address_t *address,
4664e13b1fa5SApple OSS Distributions mach_vm_size_t *size,
4665e13b1fa5SApple OSS Distributions uint32_t flags
4666e13b1fa5SApple OSS Distributions )
4667c1dac77fSApple OSS Distributions {
4668c1dac77fSApple OSS Distributions IOReturn err;
4669c1dac77fSApple OSS Distributions IOMemoryMap * map;
4670c1dac77fSApple OSS Distributions
4671e13b1fa5SApple OSS Distributions CHECK( IOUserClient, connection, client );
4672c1dac77fSApple OSS Distributions
4673a5e72196SApple OSS Distributions if (!into_task) {
4674a5e72196SApple OSS Distributions return kIOReturnBadArgument;
4675a5e72196SApple OSS Distributions }
46760f3703acSApple OSS Distributions
4677855239e5SApple OSS Distributions IOStatisticsClientCall();
467894d3b452SApple OSS Distributions
467994d3b452SApple OSS Distributions client->ipcEnter(client->defaultLocking ? kIPCLockWrite : kIPCLockNone);
4680e13b1fa5SApple OSS Distributions map = client->mapClientMemory64( memory_type, into_task, flags, *address );
4681c1dac77fSApple OSS Distributions
4682c1dac77fSApple OSS Distributions if (map) {
4683e13b1fa5SApple OSS Distributions *address = map->getAddress();
4684a5e72196SApple OSS Distributions if (size) {
4685e13b1fa5SApple OSS Distributions *size = map->getSize();
4686a5e72196SApple OSS Distributions }
4687c1dac77fSApple OSS Distributions
4688e13b1fa5SApple OSS Distributions if (client->sharedInstance
4689e13b1fa5SApple OSS Distributions || (into_task != current_task())) {
4690c1dac77fSApple OSS Distributions // push a name out to the task owning the map,
4691c1dac77fSApple OSS Distributions // so we can clean up maps
4692e13b1fa5SApple OSS Distributions mach_port_name_t name __unused =
4693368ad365SApple OSS Distributions IOMachPort::makeSendRightForTask(
4694e13b1fa5SApple OSS Distributions into_task, map, IKOT_IOKIT_OBJECT );
4695cc9a6355SApple OSS Distributions map->release();
4696c1dac77fSApple OSS Distributions } else {
4697c1dac77fSApple OSS Distributions // keep it with the user client
4698c1dac77fSApple OSS Distributions IOLockLock( gIOObjectPortLock);
4699a5e72196SApple OSS Distributions if (NULL == client->mappings) {
4700c1dac77fSApple OSS Distributions client->mappings = OSSet::withCapacity(2);
4701a5e72196SApple OSS Distributions }
4702a5e72196SApple OSS Distributions if (client->mappings) {
4703c1dac77fSApple OSS Distributions client->mappings->setObject( map);
4704a5e72196SApple OSS Distributions }
4705c1dac77fSApple OSS Distributions IOLockUnlock( gIOObjectPortLock);
4706c1dac77fSApple OSS Distributions map->release();
4707c1dac77fSApple OSS Distributions }
4708c1dac77fSApple OSS Distributions err = kIOReturnSuccess;
4709a5e72196SApple OSS Distributions } else {
4710c1dac77fSApple OSS Distributions err = kIOReturnBadArgument;
4711a5e72196SApple OSS Distributions }
4712c1dac77fSApple OSS Distributions
471394d3b452SApple OSS Distributions client->ipcExit(client->defaultLocking ? kIPCLockWrite : kIPCLockNone);
471494d3b452SApple OSS Distributions
4715a5e72196SApple OSS Distributions return err;
4716c1dac77fSApple OSS Distributions }
4717c1dac77fSApple OSS Distributions
4718e13b1fa5SApple OSS Distributions /* Routine is_io_connect_map_memory */
4719a5e72196SApple OSS Distributions kern_return_t
is_io_connect_map_memory(io_object_t connect,uint32_t type,task_t task,uint32_t * mapAddr,uint32_t * mapSize,uint32_t flags)4720a5e72196SApple OSS Distributions is_io_connect_map_memory(
4721e13b1fa5SApple OSS Distributions io_object_t connect,
4722e13b1fa5SApple OSS Distributions uint32_t type,
4723e13b1fa5SApple OSS Distributions task_t task,
4724a3bb9fccSApple OSS Distributions uint32_t * mapAddr,
4725a3bb9fccSApple OSS Distributions uint32_t * mapSize,
4726e13b1fa5SApple OSS Distributions uint32_t flags )
4727e13b1fa5SApple OSS Distributions {
4728e13b1fa5SApple OSS Distributions IOReturn err;
4729e13b1fa5SApple OSS Distributions mach_vm_address_t address;
4730e13b1fa5SApple OSS Distributions mach_vm_size_t size;
4731e13b1fa5SApple OSS Distributions
4732e13b1fa5SApple OSS Distributions address = SCALAR64(*mapAddr);
4733e13b1fa5SApple OSS Distributions size = SCALAR64(*mapSize);
4734e13b1fa5SApple OSS Distributions
4735e13b1fa5SApple OSS Distributions err = is_io_connect_map_memory_into_task(connect, type, task, &address, &size, flags);
4736e13b1fa5SApple OSS Distributions
4737e13b1fa5SApple OSS Distributions *mapAddr = SCALAR32(address);
4738e13b1fa5SApple OSS Distributions *mapSize = SCALAR32(size);
4739e13b1fa5SApple OSS Distributions
4740a5e72196SApple OSS Distributions return err;
4741e13b1fa5SApple OSS Distributions }
4742855239e5SApple OSS Distributions } /* extern "C" */
4743855239e5SApple OSS Distributions
4744a5e72196SApple OSS Distributions IOMemoryMap *
removeMappingForDescriptor(IOMemoryDescriptor * mem)4745a5e72196SApple OSS Distributions IOUserClient::removeMappingForDescriptor(IOMemoryDescriptor * mem)
474614e3d835SApple OSS Distributions {
474714e3d835SApple OSS Distributions OSIterator * iter;
4748a5e72196SApple OSS Distributions IOMemoryMap * map = NULL;
474914e3d835SApple OSS Distributions
475014e3d835SApple OSS Distributions IOLockLock(gIOObjectPortLock);
475114e3d835SApple OSS Distributions
475214e3d835SApple OSS Distributions iter = OSCollectionIterator::withCollection(mappings);
4753a5e72196SApple OSS Distributions if (iter) {
4754a5e72196SApple OSS Distributions while ((map = OSDynamicCast(IOMemoryMap, iter->getNextObject()))) {
4755a5e72196SApple OSS Distributions if (mem == map->getMemoryDescriptor()) {
475614e3d835SApple OSS Distributions map->retain();
475714e3d835SApple OSS Distributions mappings->removeObject(map);
475814e3d835SApple OSS Distributions break;
475914e3d835SApple OSS Distributions }
476014e3d835SApple OSS Distributions }
476114e3d835SApple OSS Distributions iter->release();
476214e3d835SApple OSS Distributions }
476314e3d835SApple OSS Distributions
476414e3d835SApple OSS Distributions IOLockUnlock(gIOObjectPortLock);
476514e3d835SApple OSS Distributions
4766a5e72196SApple OSS Distributions return map;
476714e3d835SApple OSS Distributions }
476814e3d835SApple OSS Distributions
4769855239e5SApple OSS Distributions extern "C" {
4770e13b1fa5SApple OSS Distributions /* Routine io_connect_unmap_memory_from_task */
4771a5e72196SApple OSS Distributions kern_return_t
is_io_connect_unmap_memory_from_task(io_connect_t connection,uint32_t memory_type,task_t from_task,mach_vm_address_t address)4772a5e72196SApple OSS Distributions is_io_connect_unmap_memory_from_task
4773e13b1fa5SApple OSS Distributions (
4774e13b1fa5SApple OSS Distributions io_connect_t connection,
4775e13b1fa5SApple OSS Distributions uint32_t memory_type,
4776e13b1fa5SApple OSS Distributions task_t from_task,
4777e13b1fa5SApple OSS Distributions mach_vm_address_t address)
4778c1dac77fSApple OSS Distributions {
4779c1dac77fSApple OSS Distributions IOReturn err;
4780c1dac77fSApple OSS Distributions IOOptionBits options = 0;
4781a5e72196SApple OSS Distributions IOMemoryDescriptor * memory = NULL;
4782c1dac77fSApple OSS Distributions IOMemoryMap * map;
4783c1dac77fSApple OSS Distributions
4784e13b1fa5SApple OSS Distributions CHECK( IOUserClient, connection, client );
4785c1dac77fSApple OSS Distributions
4786a5e72196SApple OSS Distributions if (!from_task) {
4787a5e72196SApple OSS Distributions return kIOReturnBadArgument;
4788a5e72196SApple OSS Distributions }
47890f3703acSApple OSS Distributions
4790855239e5SApple OSS Distributions IOStatisticsClientCall();
479194d3b452SApple OSS Distributions
479294d3b452SApple OSS Distributions client->ipcEnter(client->defaultLocking ? kIPCLockWrite : kIPCLockNone);
4793e13b1fa5SApple OSS Distributions err = client->clientMemoryForType((UInt32) memory_type, &options, &memory );
4794c1dac77fSApple OSS Distributions
4795c1dac77fSApple OSS Distributions if (memory && (kIOReturnSuccess == err)) {
4796c1dac77fSApple OSS Distributions options = (options & ~kIOMapUserOptionsMask)
4797c1dac77fSApple OSS Distributions | kIOMapAnywhere | kIOMapReference;
4798c1dac77fSApple OSS Distributions
4799e13b1fa5SApple OSS Distributions map = memory->createMappingInTask( from_task, address, options );
4800c1dac77fSApple OSS Distributions memory->release();
4801a5e72196SApple OSS Distributions if (map) {
4802c1dac77fSApple OSS Distributions IOLockLock( gIOObjectPortLock);
4803a5e72196SApple OSS Distributions if (client->mappings) {
4804c1dac77fSApple OSS Distributions client->mappings->removeObject( map);
4805a5e72196SApple OSS Distributions }
4806c1dac77fSApple OSS Distributions IOLockUnlock( gIOObjectPortLock);
480714e3d835SApple OSS Distributions
480814e3d835SApple OSS Distributions mach_port_name_t name = 0;
4809bb611c8fSApple OSS Distributions bool is_shared_instance_or_from_current_task = from_task != current_task() || client->sharedInstance;
4810bb611c8fSApple OSS Distributions if (is_shared_instance_or_from_current_task) {
4811e13b1fa5SApple OSS Distributions name = IOMachPort::makeSendRightForTask( from_task, map, IKOT_IOKIT_OBJECT );
4812cc9a6355SApple OSS Distributions map->release();
4813cc9a6355SApple OSS Distributions }
4814cc9a6355SApple OSS Distributions
4815a5e72196SApple OSS Distributions if (name) {
48163ca3bd55SApple OSS Distributions map->userClientUnmap();
4817e13b1fa5SApple OSS Distributions err = iokit_mod_send_right( from_task, name, -2 );
481814e3d835SApple OSS Distributions err = kIOReturnSuccess;
4819a5e72196SApple OSS Distributions } else {
48208149afccSApple OSS Distributions IOMachPort::releasePortForObject( map, IKOT_IOKIT_OBJECT );
4821a5e72196SApple OSS Distributions }
4822bb611c8fSApple OSS Distributions if (!is_shared_instance_or_from_current_task) {
4823c1dac77fSApple OSS Distributions map->release();
482414e3d835SApple OSS Distributions }
4825a5e72196SApple OSS Distributions } else {
4826c1dac77fSApple OSS Distributions err = kIOReturnBadArgument;
4827c1dac77fSApple OSS Distributions }
4828c1dac77fSApple OSS Distributions }
4829c1dac77fSApple OSS Distributions
483094d3b452SApple OSS Distributions client->ipcExit(client->defaultLocking ? kIPCLockWrite : kIPCLockNone);
483194d3b452SApple OSS Distributions
4832a5e72196SApple OSS Distributions return err;
4833a5e72196SApple OSS Distributions }
4834a5e72196SApple OSS Distributions
4835a5e72196SApple OSS Distributions kern_return_t
is_io_connect_unmap_memory(io_object_t connect,uint32_t type,task_t task,uint32_t mapAddr)4836a5e72196SApple OSS Distributions is_io_connect_unmap_memory(
4837e13b1fa5SApple OSS Distributions io_object_t connect,
4838e13b1fa5SApple OSS Distributions uint32_t type,
4839e13b1fa5SApple OSS Distributions task_t task,
4840a3bb9fccSApple OSS Distributions uint32_t mapAddr )
4841e13b1fa5SApple OSS Distributions {
4842e13b1fa5SApple OSS Distributions IOReturn err;
4843e13b1fa5SApple OSS Distributions mach_vm_address_t address;
4844e13b1fa5SApple OSS Distributions
4845e13b1fa5SApple OSS Distributions address = SCALAR64(mapAddr);
4846e13b1fa5SApple OSS Distributions
4847e13b1fa5SApple OSS Distributions err = is_io_connect_unmap_memory_from_task(connect, type, task, mapAddr);
4848e13b1fa5SApple OSS Distributions
4849a5e72196SApple OSS Distributions return err;
4850e13b1fa5SApple OSS Distributions }
4851e13b1fa5SApple OSS Distributions
4852c1dac77fSApple OSS Distributions
4853c1dac77fSApple OSS Distributions /* Routine io_connect_add_client */
4854a5e72196SApple OSS Distributions kern_return_t
is_io_connect_add_client(io_connect_t connection,io_object_t connect_to)4855a5e72196SApple OSS Distributions is_io_connect_add_client(
485694d3b452SApple OSS Distributions io_connect_t connection,
4857c1dac77fSApple OSS Distributions io_object_t connect_to)
4858c1dac77fSApple OSS Distributions {
4859c1dac77fSApple OSS Distributions CHECK( IOUserClient, connection, client );
4860c1dac77fSApple OSS Distributions CHECK( IOUserClient, connect_to, to );
4861c1dac77fSApple OSS Distributions
4862bb611c8fSApple OSS Distributions IOReturn ret;
4863bb611c8fSApple OSS Distributions
4864855239e5SApple OSS Distributions IOStatisticsClientCall();
486594d3b452SApple OSS Distributions
486694d3b452SApple OSS Distributions client->ipcEnter(client->defaultLocking ? kIPCLockWrite : kIPCLockNone);
4867bb611c8fSApple OSS Distributions ret = client->connectClient( to );
486894d3b452SApple OSS Distributions client->ipcExit(client->defaultLocking ? kIPCLockWrite : kIPCLockNone);
486994d3b452SApple OSS Distributions
4870bb611c8fSApple OSS Distributions return ret;
4871c1dac77fSApple OSS Distributions }
4872c1dac77fSApple OSS Distributions
4873c1dac77fSApple OSS Distributions
4874c1dac77fSApple OSS Distributions /* Routine io_connect_set_properties */
4875a5e72196SApple OSS Distributions kern_return_t
is_io_connect_set_properties(io_connect_t connection,io_buf_ptr_t properties,mach_msg_type_number_t propertiesCnt,kern_return_t * result)4876a5e72196SApple OSS Distributions is_io_connect_set_properties(
487794d3b452SApple OSS Distributions io_connect_t connection,
4878c1dac77fSApple OSS Distributions io_buf_ptr_t properties,
4879c1dac77fSApple OSS Distributions mach_msg_type_number_t propertiesCnt,
4880e13b1fa5SApple OSS Distributions kern_return_t * result)
4881c1dac77fSApple OSS Distributions {
4882a5e72196SApple OSS Distributions return is_io_registry_entry_set_properties( connection, properties, propertiesCnt, result );
4883c1dac77fSApple OSS Distributions }
4884c1dac77fSApple OSS Distributions
4885d0c1fef6SApple OSS Distributions /* Routine io_user_client_method */
4886a5e72196SApple OSS Distributions kern_return_t
is_io_connect_method_var_output(io_connect_t connection,uint32_t selector,io_scalar_inband64_t scalar_input,mach_msg_type_number_t scalar_inputCnt,io_struct_inband_t inband_input,mach_msg_type_number_t inband_inputCnt,mach_vm_address_t ool_input,mach_vm_size_t ool_input_size,io_struct_inband_t inband_output,mach_msg_type_number_t * inband_outputCnt,io_scalar_inband64_t scalar_output,mach_msg_type_number_t * scalar_outputCnt,io_buf_ptr_t * var_output,mach_msg_type_number_t * var_outputCnt)4887a5e72196SApple OSS Distributions is_io_connect_method_var_output
4888d0c1fef6SApple OSS Distributions (
4889d0c1fef6SApple OSS Distributions io_connect_t connection,
4890d0c1fef6SApple OSS Distributions uint32_t selector,
4891d0c1fef6SApple OSS Distributions io_scalar_inband64_t scalar_input,
4892d0c1fef6SApple OSS Distributions mach_msg_type_number_t scalar_inputCnt,
4893d0c1fef6SApple OSS Distributions io_struct_inband_t inband_input,
4894d0c1fef6SApple OSS Distributions mach_msg_type_number_t inband_inputCnt,
4895d0c1fef6SApple OSS Distributions mach_vm_address_t ool_input,
4896d0c1fef6SApple OSS Distributions mach_vm_size_t ool_input_size,
4897d0c1fef6SApple OSS Distributions io_struct_inband_t inband_output,
4898d0c1fef6SApple OSS Distributions mach_msg_type_number_t *inband_outputCnt,
4899d0c1fef6SApple OSS Distributions io_scalar_inband64_t scalar_output,
4900d0c1fef6SApple OSS Distributions mach_msg_type_number_t *scalar_outputCnt,
4901d0c1fef6SApple OSS Distributions io_buf_ptr_t *var_output,
4902d0c1fef6SApple OSS Distributions mach_msg_type_number_t *var_outputCnt
4903d0c1fef6SApple OSS Distributions )
4904d0c1fef6SApple OSS Distributions {
4905d0c1fef6SApple OSS Distributions CHECK( IOUserClient, connection, client );
4906d0c1fef6SApple OSS Distributions
4907d0c1fef6SApple OSS Distributions IOExternalMethodArguments args;
4908d0c1fef6SApple OSS Distributions IOReturn ret;
4909a5e72196SApple OSS Distributions IOMemoryDescriptor * inputMD = NULL;
4910a5e72196SApple OSS Distributions OSObject * structureVariableOutputData = NULL;
4911d0c1fef6SApple OSS Distributions
4912d0c1fef6SApple OSS Distributions bzero(&args.__reserved[0], sizeof(args.__reserved));
491388cc0b97SApple OSS Distributions args.__reservedA = 0;
4914d0c1fef6SApple OSS Distributions args.version = kIOExternalMethodArgumentsCurrentVersion;
4915d0c1fef6SApple OSS Distributions
4916d0c1fef6SApple OSS Distributions args.selector = selector;
4917d0c1fef6SApple OSS Distributions
4918d0c1fef6SApple OSS Distributions args.asyncWakePort = MACH_PORT_NULL;
4919a5e72196SApple OSS Distributions args.asyncReference = NULL;
4920d0c1fef6SApple OSS Distributions args.asyncReferenceCount = 0;
4921d0c1fef6SApple OSS Distributions args.structureVariableOutputData = &structureVariableOutputData;
4922d0c1fef6SApple OSS Distributions
4923d0c1fef6SApple OSS Distributions args.scalarInput = scalar_input;
4924d0c1fef6SApple OSS Distributions args.scalarInputCount = scalar_inputCnt;
4925d0c1fef6SApple OSS Distributions args.structureInput = inband_input;
4926d0c1fef6SApple OSS Distributions args.structureInputSize = inband_inputCnt;
4927d0c1fef6SApple OSS Distributions
4928a5e72196SApple OSS Distributions if (ool_input && (ool_input_size <= sizeof(io_struct_inband_t))) {
4929a5e72196SApple OSS Distributions return kIOReturnIPCError;
4930a5e72196SApple OSS Distributions }
493176e12aa3SApple OSS Distributions
4932a5e72196SApple OSS Distributions if (ool_input) {
4933d0c1fef6SApple OSS Distributions inputMD = IOMemoryDescriptor::withAddressRange(ool_input, ool_input_size,
493476e12aa3SApple OSS Distributions kIODirectionOut | kIOMemoryMapCopyOnWrite,
493576e12aa3SApple OSS Distributions current_task());
4936a5e72196SApple OSS Distributions }
4937d0c1fef6SApple OSS Distributions
4938d0c1fef6SApple OSS Distributions args.structureInputDescriptor = inputMD;
4939d0c1fef6SApple OSS Distributions
4940d0c1fef6SApple OSS Distributions args.scalarOutput = scalar_output;
4941d0c1fef6SApple OSS Distributions args.scalarOutputCount = *scalar_outputCnt;
4942a3bb9fccSApple OSS Distributions bzero(&scalar_output[0], *scalar_outputCnt * sizeof(scalar_output[0]));
4943d0c1fef6SApple OSS Distributions args.structureOutput = inband_output;
4944d0c1fef6SApple OSS Distributions args.structureOutputSize = *inband_outputCnt;
4945d0c1fef6SApple OSS Distributions args.structureOutputDescriptor = NULL;
4946d0c1fef6SApple OSS Distributions args.structureOutputDescriptorSize = 0;
4947d0c1fef6SApple OSS Distributions
4948d0c1fef6SApple OSS Distributions IOStatisticsClientCall();
4949bb611c8fSApple OSS Distributions ret = kIOReturnSuccess;
4950bb611c8fSApple OSS Distributions
4951bb611c8fSApple OSS Distributions io_filter_policy_t filterPolicy = client->filterForTask(current_task(), 0);
4952bb611c8fSApple OSS Distributions if (filterPolicy && gIOUCFilterCallbacks->io_filter_applier) {
4953e6231be0SApple OSS Distributions ret = gIOUCFilterCallbacks->io_filter_applier(client, filterPolicy, io_filter_type_external_method, selector);
4954bb611c8fSApple OSS Distributions }
49555c2921b0SApple OSS Distributions
4956bb611c8fSApple OSS Distributions if (kIOReturnSuccess == ret) {
49575c2921b0SApple OSS Distributions ret = client->callExternalMethod(selector, &args);
4958bb611c8fSApple OSS Distributions }
4959d0c1fef6SApple OSS Distributions
4960d0c1fef6SApple OSS Distributions *scalar_outputCnt = args.scalarOutputCount;
4961d0c1fef6SApple OSS Distributions *inband_outputCnt = args.structureOutputSize;
4962d0c1fef6SApple OSS Distributions
4963a5e72196SApple OSS Distributions if (var_outputCnt && var_output && (kIOReturnSuccess == ret)) {
4964d0c1fef6SApple OSS Distributions OSSerialize * serialize;
4965d0c1fef6SApple OSS Distributions OSData * data;
4966bb611c8fSApple OSS Distributions unsigned int len;
4967d0c1fef6SApple OSS Distributions
4968a5e72196SApple OSS Distributions if ((serialize = OSDynamicCast(OSSerialize, structureVariableOutputData))) {
4969d0c1fef6SApple OSS Distributions len = serialize->getLength();
4970d0c1fef6SApple OSS Distributions *var_outputCnt = len;
4971d0c1fef6SApple OSS Distributions ret = copyoutkdata(serialize->text(), len, var_output);
4972a5e72196SApple OSS Distributions } else if ((data = OSDynamicCast(OSData, structureVariableOutputData))) {
49735c2921b0SApple OSS Distributions data->clipForCopyout();
4974d0c1fef6SApple OSS Distributions len = data->getLength();
4975d0c1fef6SApple OSS Distributions *var_outputCnt = len;
4976d0c1fef6SApple OSS Distributions ret = copyoutkdata(data->getBytesNoCopy(), len, var_output);
4977a5e72196SApple OSS Distributions } else {
4978d0c1fef6SApple OSS Distributions ret = kIOReturnUnderrun;
4979d0c1fef6SApple OSS Distributions }
4980d0c1fef6SApple OSS Distributions }
4981d0c1fef6SApple OSS Distributions
4982a5e72196SApple OSS Distributions if (inputMD) {
4983d0c1fef6SApple OSS Distributions inputMD->release();
4984a5e72196SApple OSS Distributions }
4985a5e72196SApple OSS Distributions if (structureVariableOutputData) {
4986d0c1fef6SApple OSS Distributions structureVariableOutputData->release();
4987a5e72196SApple OSS Distributions }
4988d0c1fef6SApple OSS Distributions
4989a5e72196SApple OSS Distributions return ret;
4990d0c1fef6SApple OSS Distributions }
4991c1dac77fSApple OSS Distributions
4992e13b1fa5SApple OSS Distributions /* Routine io_user_client_method */
4993a5e72196SApple OSS Distributions kern_return_t
is_io_connect_method(io_connect_t connection,uint32_t selector,io_scalar_inband64_t scalar_input,mach_msg_type_number_t scalar_inputCnt,io_struct_inband_t inband_input,mach_msg_type_number_t inband_inputCnt,mach_vm_address_t ool_input,mach_vm_size_t ool_input_size,io_struct_inband_t inband_output,mach_msg_type_number_t * inband_outputCnt,io_scalar_inband64_t scalar_output,mach_msg_type_number_t * scalar_outputCnt,mach_vm_address_t ool_output,mach_vm_size_t * ool_output_size)4994a5e72196SApple OSS Distributions is_io_connect_method
4995e13b1fa5SApple OSS Distributions (
4996e13b1fa5SApple OSS Distributions io_connect_t connection,
4997e13b1fa5SApple OSS Distributions uint32_t selector,
4998e13b1fa5SApple OSS Distributions io_scalar_inband64_t scalar_input,
4999e13b1fa5SApple OSS Distributions mach_msg_type_number_t scalar_inputCnt,
5000e13b1fa5SApple OSS Distributions io_struct_inband_t inband_input,
5001e13b1fa5SApple OSS Distributions mach_msg_type_number_t inband_inputCnt,
5002e13b1fa5SApple OSS Distributions mach_vm_address_t ool_input,
5003e13b1fa5SApple OSS Distributions mach_vm_size_t ool_input_size,
5004e13b1fa5SApple OSS Distributions io_struct_inband_t inband_output,
5005e13b1fa5SApple OSS Distributions mach_msg_type_number_t *inband_outputCnt,
5006855239e5SApple OSS Distributions io_scalar_inband64_t scalar_output,
5007855239e5SApple OSS Distributions mach_msg_type_number_t *scalar_outputCnt,
5008e13b1fa5SApple OSS Distributions mach_vm_address_t ool_output,
5009e13b1fa5SApple OSS Distributions mach_vm_size_t *ool_output_size
5010e13b1fa5SApple OSS Distributions )
5011e13b1fa5SApple OSS Distributions {
5012e13b1fa5SApple OSS Distributions CHECK( IOUserClient, connection, client );
5013e13b1fa5SApple OSS Distributions
5014e13b1fa5SApple OSS Distributions IOExternalMethodArguments args;
5015e13b1fa5SApple OSS Distributions IOReturn ret;
5016a5e72196SApple OSS Distributions IOMemoryDescriptor * inputMD = NULL;
5017a5e72196SApple OSS Distributions IOMemoryDescriptor * outputMD = NULL;
5018e13b1fa5SApple OSS Distributions
5019e13b1fa5SApple OSS Distributions bzero(&args.__reserved[0], sizeof(args.__reserved));
502088cc0b97SApple OSS Distributions args.__reservedA = 0;
5021e13b1fa5SApple OSS Distributions args.version = kIOExternalMethodArgumentsCurrentVersion;
5022e13b1fa5SApple OSS Distributions
5023e13b1fa5SApple OSS Distributions args.selector = selector;
5024e13b1fa5SApple OSS Distributions
5025e13b1fa5SApple OSS Distributions args.asyncWakePort = MACH_PORT_NULL;
5026a5e72196SApple OSS Distributions args.asyncReference = NULL;
5027e13b1fa5SApple OSS Distributions args.asyncReferenceCount = 0;
5028a5e72196SApple OSS Distributions args.structureVariableOutputData = NULL;
5029e13b1fa5SApple OSS Distributions
5030e13b1fa5SApple OSS Distributions args.scalarInput = scalar_input;
5031e13b1fa5SApple OSS Distributions args.scalarInputCount = scalar_inputCnt;
5032e13b1fa5SApple OSS Distributions args.structureInput = inband_input;
5033e13b1fa5SApple OSS Distributions args.structureInputSize = inband_inputCnt;
5034e13b1fa5SApple OSS Distributions
5035a5e72196SApple OSS Distributions if (ool_input && (ool_input_size <= sizeof(io_struct_inband_t))) {
5036a5e72196SApple OSS Distributions return kIOReturnIPCError;
5037a5e72196SApple OSS Distributions }
5038bb611c8fSApple OSS Distributions if (ool_output) {
5039bb611c8fSApple OSS Distributions if (*ool_output_size <= sizeof(io_struct_inband_t)) {
5040a5e72196SApple OSS Distributions return kIOReturnIPCError;
5041a5e72196SApple OSS Distributions }
5042bb611c8fSApple OSS Distributions if (*ool_output_size > UINT_MAX) {
5043bb611c8fSApple OSS Distributions return kIOReturnIPCError;
5044bb611c8fSApple OSS Distributions }
5045bb611c8fSApple OSS Distributions }
504676e12aa3SApple OSS Distributions
5047a5e72196SApple OSS Distributions if (ool_input) {
5048e13b1fa5SApple OSS Distributions inputMD = IOMemoryDescriptor::withAddressRange(ool_input, ool_input_size,
504976e12aa3SApple OSS Distributions kIODirectionOut | kIOMemoryMapCopyOnWrite,
505076e12aa3SApple OSS Distributions current_task());
5051a5e72196SApple OSS Distributions }
5052e13b1fa5SApple OSS Distributions
5053e13b1fa5SApple OSS Distributions args.structureInputDescriptor = inputMD;
5054e13b1fa5SApple OSS Distributions
5055e13b1fa5SApple OSS Distributions args.scalarOutput = scalar_output;
5056e13b1fa5SApple OSS Distributions args.scalarOutputCount = *scalar_outputCnt;
5057a3bb9fccSApple OSS Distributions bzero(&scalar_output[0], *scalar_outputCnt * sizeof(scalar_output[0]));
5058e13b1fa5SApple OSS Distributions args.structureOutput = inband_output;
5059e13b1fa5SApple OSS Distributions args.structureOutputSize = *inband_outputCnt;
5060e13b1fa5SApple OSS Distributions
5061a5e72196SApple OSS Distributions if (ool_output && ool_output_size) {
5062e13b1fa5SApple OSS Distributions outputMD = IOMemoryDescriptor::withAddressRange(ool_output, *ool_output_size,
5063e13b1fa5SApple OSS Distributions kIODirectionIn, current_task());
5064e13b1fa5SApple OSS Distributions }
5065e13b1fa5SApple OSS Distributions
5066e13b1fa5SApple OSS Distributions args.structureOutputDescriptor = outputMD;
5067bb611c8fSApple OSS Distributions args.structureOutputDescriptorSize = ool_output_size
5068bb611c8fSApple OSS Distributions ? ((typeof(args.structureOutputDescriptorSize)) * ool_output_size)
5069bb611c8fSApple OSS Distributions : 0;
5070e13b1fa5SApple OSS Distributions
5071855239e5SApple OSS Distributions IOStatisticsClientCall();
5072bb611c8fSApple OSS Distributions ret = kIOReturnSuccess;
5073bb611c8fSApple OSS Distributions io_filter_policy_t filterPolicy = client->filterForTask(current_task(), 0);
5074bb611c8fSApple OSS Distributions if (filterPolicy && gIOUCFilterCallbacks->io_filter_applier) {
5075e6231be0SApple OSS Distributions ret = gIOUCFilterCallbacks->io_filter_applier(client, filterPolicy, io_filter_type_external_method, selector);
5076bb611c8fSApple OSS Distributions }
5077bb611c8fSApple OSS Distributions if (kIOReturnSuccess == ret) {
50785c2921b0SApple OSS Distributions ret = client->callExternalMethod( selector, &args );
5079bb611c8fSApple OSS Distributions }
5080e13b1fa5SApple OSS Distributions
5081e13b1fa5SApple OSS Distributions *scalar_outputCnt = args.scalarOutputCount;
5082e13b1fa5SApple OSS Distributions *inband_outputCnt = args.structureOutputSize;
5083e13b1fa5SApple OSS Distributions *ool_output_size = args.structureOutputDescriptorSize;
5084e13b1fa5SApple OSS Distributions
5085a5e72196SApple OSS Distributions if (inputMD) {
5086e13b1fa5SApple OSS Distributions inputMD->release();
5087a5e72196SApple OSS Distributions }
5088a5e72196SApple OSS Distributions if (outputMD) {
5089e13b1fa5SApple OSS Distributions outputMD->release();
5090a5e72196SApple OSS Distributions }
5091e13b1fa5SApple OSS Distributions
5092a5e72196SApple OSS Distributions return ret;
5093e13b1fa5SApple OSS Distributions }
5094e13b1fa5SApple OSS Distributions
5095e13b1fa5SApple OSS Distributions /* Routine io_async_user_client_method */
5096a5e72196SApple OSS Distributions kern_return_t
is_io_connect_async_method(io_connect_t connection,mach_port_t wake_port,io_async_ref64_t reference,mach_msg_type_number_t referenceCnt,uint32_t selector,io_scalar_inband64_t scalar_input,mach_msg_type_number_t scalar_inputCnt,io_struct_inband_t inband_input,mach_msg_type_number_t inband_inputCnt,mach_vm_address_t ool_input,mach_vm_size_t ool_input_size,io_struct_inband_t inband_output,mach_msg_type_number_t * inband_outputCnt,io_scalar_inband64_t scalar_output,mach_msg_type_number_t * scalar_outputCnt,mach_vm_address_t ool_output,mach_vm_size_t * ool_output_size)5097a5e72196SApple OSS Distributions is_io_connect_async_method
5098e13b1fa5SApple OSS Distributions (
5099e13b1fa5SApple OSS Distributions io_connect_t connection,
5100e13b1fa5SApple OSS Distributions mach_port_t wake_port,
5101e13b1fa5SApple OSS Distributions io_async_ref64_t reference,
5102e13b1fa5SApple OSS Distributions mach_msg_type_number_t referenceCnt,
5103e13b1fa5SApple OSS Distributions uint32_t selector,
5104e13b1fa5SApple OSS Distributions io_scalar_inband64_t scalar_input,
5105e13b1fa5SApple OSS Distributions mach_msg_type_number_t scalar_inputCnt,
5106e13b1fa5SApple OSS Distributions io_struct_inband_t inband_input,
5107e13b1fa5SApple OSS Distributions mach_msg_type_number_t inband_inputCnt,
5108e13b1fa5SApple OSS Distributions mach_vm_address_t ool_input,
5109e13b1fa5SApple OSS Distributions mach_vm_size_t ool_input_size,
5110e13b1fa5SApple OSS Distributions io_struct_inband_t inband_output,
5111e13b1fa5SApple OSS Distributions mach_msg_type_number_t *inband_outputCnt,
5112855239e5SApple OSS Distributions io_scalar_inband64_t scalar_output,
5113855239e5SApple OSS Distributions mach_msg_type_number_t *scalar_outputCnt,
5114e13b1fa5SApple OSS Distributions mach_vm_address_t ool_output,
5115e13b1fa5SApple OSS Distributions mach_vm_size_t * ool_output_size
5116e13b1fa5SApple OSS Distributions )
5117e13b1fa5SApple OSS Distributions {
5118e13b1fa5SApple OSS Distributions CHECK( IOUserClient, connection, client );
5119e13b1fa5SApple OSS Distributions
5120e13b1fa5SApple OSS Distributions IOExternalMethodArguments args;
5121e13b1fa5SApple OSS Distributions IOReturn ret;
5122a5e72196SApple OSS Distributions IOMemoryDescriptor * inputMD = NULL;
5123a5e72196SApple OSS Distributions IOMemoryDescriptor * outputMD = NULL;
5124e13b1fa5SApple OSS Distributions
5125bb611c8fSApple OSS Distributions if (referenceCnt < 1) {
5126bb611c8fSApple OSS Distributions return kIOReturnBadArgument;
5127bb611c8fSApple OSS Distributions }
5128bb611c8fSApple OSS Distributions
5129e13b1fa5SApple OSS Distributions bzero(&args.__reserved[0], sizeof(args.__reserved));
513088cc0b97SApple OSS Distributions args.__reservedA = 0;
5131e13b1fa5SApple OSS Distributions args.version = kIOExternalMethodArgumentsCurrentVersion;
5132e13b1fa5SApple OSS Distributions
5133e13b1fa5SApple OSS Distributions reference[0] = (io_user_reference_t) wake_port;
5134a5e72196SApple OSS Distributions if (vm_map_is_64bit(get_task_map(current_task()))) {
5135e13b1fa5SApple OSS Distributions reference[0] |= kIOUCAsync64Flag;
5136a5e72196SApple OSS Distributions }
5137e13b1fa5SApple OSS Distributions
5138e13b1fa5SApple OSS Distributions args.selector = selector;
5139e13b1fa5SApple OSS Distributions
5140e13b1fa5SApple OSS Distributions args.asyncWakePort = wake_port;
5141e13b1fa5SApple OSS Distributions args.asyncReference = reference;
5142e13b1fa5SApple OSS Distributions args.asyncReferenceCount = referenceCnt;
5143e13b1fa5SApple OSS Distributions
5144a5e72196SApple OSS Distributions args.structureVariableOutputData = NULL;
514576e12aa3SApple OSS Distributions
5146e13b1fa5SApple OSS Distributions args.scalarInput = scalar_input;
5147e13b1fa5SApple OSS Distributions args.scalarInputCount = scalar_inputCnt;
5148e13b1fa5SApple OSS Distributions args.structureInput = inband_input;
5149e13b1fa5SApple OSS Distributions args.structureInputSize = inband_inputCnt;
5150e13b1fa5SApple OSS Distributions
5151a5e72196SApple OSS Distributions if (ool_input && (ool_input_size <= sizeof(io_struct_inband_t))) {
5152a5e72196SApple OSS Distributions return kIOReturnIPCError;
5153a5e72196SApple OSS Distributions }
5154bb611c8fSApple OSS Distributions if (ool_output) {
5155bb611c8fSApple OSS Distributions if (*ool_output_size <= sizeof(io_struct_inband_t)) {
5156a5e72196SApple OSS Distributions return kIOReturnIPCError;
5157a5e72196SApple OSS Distributions }
5158bb611c8fSApple OSS Distributions if (*ool_output_size > UINT_MAX) {
5159bb611c8fSApple OSS Distributions return kIOReturnIPCError;
5160bb611c8fSApple OSS Distributions }
5161bb611c8fSApple OSS Distributions }
516276e12aa3SApple OSS Distributions
5163a5e72196SApple OSS Distributions if (ool_input) {
5164e13b1fa5SApple OSS Distributions inputMD = IOMemoryDescriptor::withAddressRange(ool_input, ool_input_size,
516576e12aa3SApple OSS Distributions kIODirectionOut | kIOMemoryMapCopyOnWrite,
516676e12aa3SApple OSS Distributions current_task());
5167a5e72196SApple OSS Distributions }
5168e13b1fa5SApple OSS Distributions
5169e13b1fa5SApple OSS Distributions args.structureInputDescriptor = inputMD;
5170e13b1fa5SApple OSS Distributions
5171e13b1fa5SApple OSS Distributions args.scalarOutput = scalar_output;
5172e13b1fa5SApple OSS Distributions args.scalarOutputCount = *scalar_outputCnt;
5173a3bb9fccSApple OSS Distributions bzero(&scalar_output[0], *scalar_outputCnt * sizeof(scalar_output[0]));
5174e13b1fa5SApple OSS Distributions args.structureOutput = inband_output;
5175e13b1fa5SApple OSS Distributions args.structureOutputSize = *inband_outputCnt;
5176e13b1fa5SApple OSS Distributions
5177a5e72196SApple OSS Distributions if (ool_output) {
5178e13b1fa5SApple OSS Distributions outputMD = IOMemoryDescriptor::withAddressRange(ool_output, *ool_output_size,
5179e13b1fa5SApple OSS Distributions kIODirectionIn, current_task());
5180e13b1fa5SApple OSS Distributions }
5181e13b1fa5SApple OSS Distributions
5182e13b1fa5SApple OSS Distributions args.structureOutputDescriptor = outputMD;
5183bb611c8fSApple OSS Distributions args.structureOutputDescriptorSize = ((typeof(args.structureOutputDescriptorSize)) * ool_output_size);
5184e13b1fa5SApple OSS Distributions
5185855239e5SApple OSS Distributions IOStatisticsClientCall();
5186bb611c8fSApple OSS Distributions ret = kIOReturnSuccess;
5187bb611c8fSApple OSS Distributions io_filter_policy_t filterPolicy = client->filterForTask(current_task(), 0);
5188bb611c8fSApple OSS Distributions if (filterPolicy && gIOUCFilterCallbacks->io_filter_applier) {
5189e6231be0SApple OSS Distributions ret = gIOUCFilterCallbacks->io_filter_applier(client, filterPolicy, io_filter_type_external_async_method, selector);
5190bb611c8fSApple OSS Distributions }
5191bb611c8fSApple OSS Distributions if (kIOReturnSuccess == ret) {
51925c2921b0SApple OSS Distributions ret = client->callExternalMethod( selector, &args );
5193bb611c8fSApple OSS Distributions }
5194e13b1fa5SApple OSS Distributions
5195a5e72196SApple OSS Distributions *scalar_outputCnt = args.scalarOutputCount;
5196e13b1fa5SApple OSS Distributions *inband_outputCnt = args.structureOutputSize;
5197e13b1fa5SApple OSS Distributions *ool_output_size = args.structureOutputDescriptorSize;
5198e13b1fa5SApple OSS Distributions
5199a5e72196SApple OSS Distributions if (inputMD) {
5200e13b1fa5SApple OSS Distributions inputMD->release();
5201a5e72196SApple OSS Distributions }
5202a5e72196SApple OSS Distributions if (outputMD) {
5203e13b1fa5SApple OSS Distributions outputMD->release();
5204a5e72196SApple OSS Distributions }
5205e13b1fa5SApple OSS Distributions
5206a5e72196SApple OSS Distributions return ret;
5207e13b1fa5SApple OSS Distributions }
5208e13b1fa5SApple OSS Distributions
5209c1dac77fSApple OSS Distributions /* Routine io_connect_method_scalarI_scalarO */
5210a5e72196SApple OSS Distributions kern_return_t
is_io_connect_method_scalarI_scalarO(io_object_t connect,uint32_t index,io_scalar_inband_t input,mach_msg_type_number_t inputCount,io_scalar_inband_t output,mach_msg_type_number_t * outputCount)5211a5e72196SApple OSS Distributions is_io_connect_method_scalarI_scalarO(
5212c1dac77fSApple OSS Distributions io_object_t connect,
5213e13b1fa5SApple OSS Distributions uint32_t index,
5214e13b1fa5SApple OSS Distributions io_scalar_inband_t input,
5215e13b1fa5SApple OSS Distributions mach_msg_type_number_t inputCount,
5216e13b1fa5SApple OSS Distributions io_scalar_inband_t output,
5217e13b1fa5SApple OSS Distributions mach_msg_type_number_t * outputCount )
5218c1dac77fSApple OSS Distributions {
5219c1dac77fSApple OSS Distributions IOReturn err;
5220e13b1fa5SApple OSS Distributions uint32_t i;
5221e13b1fa5SApple OSS Distributions io_scalar_inband64_t _input;
5222e13b1fa5SApple OSS Distributions io_scalar_inband64_t _output;
5223c1dac77fSApple OSS Distributions
5224e13b1fa5SApple OSS Distributions mach_msg_type_number_t struct_outputCnt = 0;
5225e13b1fa5SApple OSS Distributions mach_vm_size_t ool_output_size = 0;
5226e13b1fa5SApple OSS Distributions
5227a3bb9fccSApple OSS Distributions bzero(&_output[0], sizeof(_output));
5228a5e72196SApple OSS Distributions for (i = 0; i < inputCount; i++) {
5229e13b1fa5SApple OSS Distributions _input[i] = SCALAR64(input[i]);
5230a5e72196SApple OSS Distributions }
5231e13b1fa5SApple OSS Distributions
5232e13b1fa5SApple OSS Distributions err = is_io_connect_method(connect, index,
5233e13b1fa5SApple OSS Distributions _input, inputCount,
5234e13b1fa5SApple OSS Distributions NULL, 0,
5235e13b1fa5SApple OSS Distributions 0, 0,
5236e13b1fa5SApple OSS Distributions NULL, &struct_outputCnt,
5237855239e5SApple OSS Distributions _output, outputCount,
5238e13b1fa5SApple OSS Distributions 0, &ool_output_size);
5239e13b1fa5SApple OSS Distributions
5240a5e72196SApple OSS Distributions for (i = 0; i < *outputCount; i++) {
5241e13b1fa5SApple OSS Distributions output[i] = SCALAR32(_output[i]);
5242e13b1fa5SApple OSS Distributions }
5243e13b1fa5SApple OSS Distributions
5244a5e72196SApple OSS Distributions return err;
5245a5e72196SApple OSS Distributions }
5246a5e72196SApple OSS Distributions
5247a5e72196SApple OSS Distributions kern_return_t
shim_io_connect_method_scalarI_scalarO(IOExternalMethod * method,IOService * object,const io_user_scalar_t * input,mach_msg_type_number_t inputCount,io_user_scalar_t * output,mach_msg_type_number_t * outputCount)5248a5e72196SApple OSS Distributions shim_io_connect_method_scalarI_scalarO(
5249e13b1fa5SApple OSS Distributions IOExternalMethod * method,
5250e13b1fa5SApple OSS Distributions IOService * object,
5251e13b1fa5SApple OSS Distributions const io_user_scalar_t * input,
5252e13b1fa5SApple OSS Distributions mach_msg_type_number_t inputCount,
5253e13b1fa5SApple OSS Distributions io_user_scalar_t * output,
5254e13b1fa5SApple OSS Distributions mach_msg_type_number_t * outputCount )
5255e13b1fa5SApple OSS Distributions {
5256e13b1fa5SApple OSS Distributions IOMethod func;
5257e13b1fa5SApple OSS Distributions io_scalar_inband_t _output;
5258e13b1fa5SApple OSS Distributions IOReturn err;
5259c1dac77fSApple OSS Distributions err = kIOReturnBadArgument;
5260e13b1fa5SApple OSS Distributions
5261a3bb9fccSApple OSS Distributions bzero(&_output[0], sizeof(_output));
5262e13b1fa5SApple OSS Distributions do {
5263a5e72196SApple OSS Distributions if (inputCount != method->count0) {
526488cc0b97SApple OSS Distributions IOLog("%s:%d %s: IOUserClient inputCount count mismatch 0x%llx 0x%llx\n", __FUNCTION__, __LINE__, object->getName(), (uint64_t)inputCount, (uint64_t)method->count0);
526588cc0b97SApple OSS Distributions DTRACE_IO2(iokit_count_mismatch, uint64_t, (uint64_t)inputCount, uint64_t, (uint64_t)method->count0);
5266c1dac77fSApple OSS Distributions continue;
5267e13b1fa5SApple OSS Distributions }
5268a5e72196SApple OSS Distributions if (*outputCount != method->count1) {
526988cc0b97SApple OSS Distributions IOLog("%s:%d %s: IOUserClient outputCount count mismatch 0x%llx 0x%llx\n", __FUNCTION__, __LINE__, object->getName(), (uint64_t)*outputCount, (uint64_t)method->count1);
527088cc0b97SApple OSS Distributions DTRACE_IO2(iokit_count_mismatch, uint64_t, (uint64_t)*outputCount, uint64_t, (uint64_t)method->count1);
5271c1dac77fSApple OSS Distributions continue;
5272e13b1fa5SApple OSS Distributions }
5273c1dac77fSApple OSS Distributions
5274c1dac77fSApple OSS Distributions func = method->func;
5275c1dac77fSApple OSS Distributions
5276c1dac77fSApple OSS Distributions switch (inputCount) {
5277c1dac77fSApple OSS Distributions case 6:
5278e13b1fa5SApple OSS Distributions err = (object->*func)( ARG32(input[0]), ARG32(input[1]), ARG32(input[2]),
5279e13b1fa5SApple OSS Distributions ARG32(input[3]), ARG32(input[4]), ARG32(input[5]));
5280c1dac77fSApple OSS Distributions break;
5281c1dac77fSApple OSS Distributions case 5:
5282e13b1fa5SApple OSS Distributions err = (object->*func)( ARG32(input[0]), ARG32(input[1]), ARG32(input[2]),
5283e13b1fa5SApple OSS Distributions ARG32(input[3]), ARG32(input[4]),
5284e13b1fa5SApple OSS Distributions &_output[0] );
5285c1dac77fSApple OSS Distributions break;
5286c1dac77fSApple OSS Distributions case 4:
5287e13b1fa5SApple OSS Distributions err = (object->*func)( ARG32(input[0]), ARG32(input[1]), ARG32(input[2]),
5288e13b1fa5SApple OSS Distributions ARG32(input[3]),
5289e13b1fa5SApple OSS Distributions &_output[0], &_output[1] );
5290c1dac77fSApple OSS Distributions break;
5291c1dac77fSApple OSS Distributions case 3:
5292e13b1fa5SApple OSS Distributions err = (object->*func)( ARG32(input[0]), ARG32(input[1]), ARG32(input[2]),
5293e13b1fa5SApple OSS Distributions &_output[0], &_output[1], &_output[2] );
5294c1dac77fSApple OSS Distributions break;
5295c1dac77fSApple OSS Distributions case 2:
5296e13b1fa5SApple OSS Distributions err = (object->*func)( ARG32(input[0]), ARG32(input[1]),
5297e13b1fa5SApple OSS Distributions &_output[0], &_output[1], &_output[2],
5298e13b1fa5SApple OSS Distributions &_output[3] );
5299c1dac77fSApple OSS Distributions break;
5300c1dac77fSApple OSS Distributions case 1:
5301e13b1fa5SApple OSS Distributions err = (object->*func)( ARG32(input[0]),
5302e13b1fa5SApple OSS Distributions &_output[0], &_output[1], &_output[2],
5303e13b1fa5SApple OSS Distributions &_output[3], &_output[4] );
5304c1dac77fSApple OSS Distributions break;
5305c1dac77fSApple OSS Distributions case 0:
5306e13b1fa5SApple OSS Distributions err = (object->*func)( &_output[0], &_output[1], &_output[2],
5307e13b1fa5SApple OSS Distributions &_output[3], &_output[4], &_output[5] );
5308c1dac77fSApple OSS Distributions break;
5309c1dac77fSApple OSS Distributions
5310c1dac77fSApple OSS Distributions default:
5311e13b1fa5SApple OSS Distributions IOLog("%s: Bad method table\n", object->getName());
5312c1dac77fSApple OSS Distributions }
5313a5e72196SApple OSS Distributions }while (false);
5314c1dac77fSApple OSS Distributions
5315e13b1fa5SApple OSS Distributions uint32_t i;
5316a5e72196SApple OSS Distributions for (i = 0; i < *outputCount; i++) {
5317e13b1fa5SApple OSS Distributions output[i] = SCALAR32(_output[i]);
5318a5e72196SApple OSS Distributions }
5319c1dac77fSApple OSS Distributions
5320a5e72196SApple OSS Distributions return err;
5321c1dac77fSApple OSS Distributions }
5322c1dac77fSApple OSS Distributions
5323e13b1fa5SApple OSS Distributions /* Routine io_async_method_scalarI_scalarO */
5324a5e72196SApple OSS Distributions kern_return_t
is_io_async_method_scalarI_scalarO(io_object_t connect,mach_port_t wake_port,io_async_ref_t reference,mach_msg_type_number_t referenceCnt,uint32_t index,io_scalar_inband_t input,mach_msg_type_number_t inputCount,io_scalar_inband_t output,mach_msg_type_number_t * outputCount)5325a5e72196SApple OSS Distributions is_io_async_method_scalarI_scalarO(
5326e13b1fa5SApple OSS Distributions io_object_t connect,
5327e13b1fa5SApple OSS Distributions mach_port_t wake_port,
5328e13b1fa5SApple OSS Distributions io_async_ref_t reference,
5329e13b1fa5SApple OSS Distributions mach_msg_type_number_t referenceCnt,
5330e13b1fa5SApple OSS Distributions uint32_t index,
5331e13b1fa5SApple OSS Distributions io_scalar_inband_t input,
5332e13b1fa5SApple OSS Distributions mach_msg_type_number_t inputCount,
5333e13b1fa5SApple OSS Distributions io_scalar_inband_t output,
5334e13b1fa5SApple OSS Distributions mach_msg_type_number_t * outputCount )
5335e13b1fa5SApple OSS Distributions {
5336e13b1fa5SApple OSS Distributions IOReturn err;
5337e13b1fa5SApple OSS Distributions uint32_t i;
5338e13b1fa5SApple OSS Distributions io_scalar_inband64_t _input;
5339e13b1fa5SApple OSS Distributions io_scalar_inband64_t _output;
5340e13b1fa5SApple OSS Distributions io_async_ref64_t _reference;
5341e13b1fa5SApple OSS Distributions
5342a5e72196SApple OSS Distributions if (referenceCnt > ASYNC_REF64_COUNT) {
5343a5e72196SApple OSS Distributions return kIOReturnBadArgument;
5344a5e72196SApple OSS Distributions }
5345a3bb9fccSApple OSS Distributions bzero(&_output[0], sizeof(_output));
5346a5e72196SApple OSS Distributions for (i = 0; i < referenceCnt; i++) {
5347e13b1fa5SApple OSS Distributions _reference[i] = REF64(reference[i]);
5348a5e72196SApple OSS Distributions }
5349a5e72196SApple OSS Distributions bzero(&_reference[referenceCnt], (ASYNC_REF64_COUNT - referenceCnt) * sizeof(_reference[0]));
5350e13b1fa5SApple OSS Distributions
5351e13b1fa5SApple OSS Distributions mach_msg_type_number_t struct_outputCnt = 0;
5352e13b1fa5SApple OSS Distributions mach_vm_size_t ool_output_size = 0;
5353e13b1fa5SApple OSS Distributions
5354a5e72196SApple OSS Distributions for (i = 0; i < inputCount; i++) {
5355e13b1fa5SApple OSS Distributions _input[i] = SCALAR64(input[i]);
5356a5e72196SApple OSS Distributions }
5357e13b1fa5SApple OSS Distributions
5358e13b1fa5SApple OSS Distributions err = is_io_connect_async_method(connect,
5359e13b1fa5SApple OSS Distributions wake_port, _reference, referenceCnt,
5360e13b1fa5SApple OSS Distributions index,
5361e13b1fa5SApple OSS Distributions _input, inputCount,
5362e13b1fa5SApple OSS Distributions NULL, 0,
5363e13b1fa5SApple OSS Distributions 0, 0,
5364e13b1fa5SApple OSS Distributions NULL, &struct_outputCnt,
5365855239e5SApple OSS Distributions _output, outputCount,
5366e13b1fa5SApple OSS Distributions 0, &ool_output_size);
5367e13b1fa5SApple OSS Distributions
5368a5e72196SApple OSS Distributions for (i = 0; i < *outputCount; i++) {
5369e13b1fa5SApple OSS Distributions output[i] = SCALAR32(_output[i]);
5370a5e72196SApple OSS Distributions }
5371e13b1fa5SApple OSS Distributions
5372a5e72196SApple OSS Distributions return err;
5373e13b1fa5SApple OSS Distributions }
5374e13b1fa5SApple OSS Distributions /* Routine io_async_method_scalarI_structureO */
5375a5e72196SApple OSS Distributions kern_return_t
is_io_async_method_scalarI_structureO(io_object_t connect,mach_port_t wake_port,io_async_ref_t reference,mach_msg_type_number_t referenceCnt,uint32_t index,io_scalar_inband_t input,mach_msg_type_number_t inputCount,io_struct_inband_t output,mach_msg_type_number_t * outputCount)5376a5e72196SApple OSS Distributions is_io_async_method_scalarI_structureO(
5377e13b1fa5SApple OSS Distributions io_object_t connect,
5378e13b1fa5SApple OSS Distributions mach_port_t wake_port,
5379e13b1fa5SApple OSS Distributions io_async_ref_t reference,
5380e13b1fa5SApple OSS Distributions mach_msg_type_number_t referenceCnt,
5381e13b1fa5SApple OSS Distributions uint32_t index,
5382e13b1fa5SApple OSS Distributions io_scalar_inband_t input,
5383e13b1fa5SApple OSS Distributions mach_msg_type_number_t inputCount,
5384e13b1fa5SApple OSS Distributions io_struct_inband_t output,
5385e13b1fa5SApple OSS Distributions mach_msg_type_number_t * outputCount )
5386e13b1fa5SApple OSS Distributions {
5387e13b1fa5SApple OSS Distributions uint32_t i;
5388e13b1fa5SApple OSS Distributions io_scalar_inband64_t _input;
5389e13b1fa5SApple OSS Distributions io_async_ref64_t _reference;
5390e13b1fa5SApple OSS Distributions
5391a5e72196SApple OSS Distributions if (referenceCnt > ASYNC_REF64_COUNT) {
5392a5e72196SApple OSS Distributions return kIOReturnBadArgument;
5393a5e72196SApple OSS Distributions }
5394a5e72196SApple OSS Distributions for (i = 0; i < referenceCnt; i++) {
5395e13b1fa5SApple OSS Distributions _reference[i] = REF64(reference[i]);
5396a5e72196SApple OSS Distributions }
5397a5e72196SApple OSS Distributions bzero(&_reference[referenceCnt], (ASYNC_REF64_COUNT - referenceCnt) * sizeof(_reference[0]));
5398e13b1fa5SApple OSS Distributions
5399e13b1fa5SApple OSS Distributions mach_msg_type_number_t scalar_outputCnt = 0;
5400e13b1fa5SApple OSS Distributions mach_vm_size_t ool_output_size = 0;
5401e13b1fa5SApple OSS Distributions
5402a5e72196SApple OSS Distributions for (i = 0; i < inputCount; i++) {
5403e13b1fa5SApple OSS Distributions _input[i] = SCALAR64(input[i]);
5404a5e72196SApple OSS Distributions }
5405e13b1fa5SApple OSS Distributions
5406a5e72196SApple OSS Distributions return is_io_connect_async_method(connect,
5407e13b1fa5SApple OSS Distributions wake_port, _reference, referenceCnt,
5408e13b1fa5SApple OSS Distributions index,
5409e13b1fa5SApple OSS Distributions _input, inputCount,
5410e13b1fa5SApple OSS Distributions NULL, 0,
5411e13b1fa5SApple OSS Distributions 0, 0,
5412e13b1fa5SApple OSS Distributions output, outputCount,
5413855239e5SApple OSS Distributions NULL, &scalar_outputCnt,
5414a5e72196SApple OSS Distributions 0, &ool_output_size);
5415e13b1fa5SApple OSS Distributions }
5416e13b1fa5SApple OSS Distributions
5417e13b1fa5SApple OSS Distributions /* Routine io_async_method_scalarI_structureI */
5418a5e72196SApple OSS Distributions kern_return_t
is_io_async_method_scalarI_structureI(io_connect_t connect,mach_port_t wake_port,io_async_ref_t reference,mach_msg_type_number_t referenceCnt,uint32_t index,io_scalar_inband_t input,mach_msg_type_number_t inputCount,io_struct_inband_t inputStruct,mach_msg_type_number_t inputStructCount)5419a5e72196SApple OSS Distributions is_io_async_method_scalarI_structureI(
5420e13b1fa5SApple OSS Distributions io_connect_t connect,
5421e13b1fa5SApple OSS Distributions mach_port_t wake_port,
5422e13b1fa5SApple OSS Distributions io_async_ref_t reference,
5423e13b1fa5SApple OSS Distributions mach_msg_type_number_t referenceCnt,
5424e13b1fa5SApple OSS Distributions uint32_t index,
5425e13b1fa5SApple OSS Distributions io_scalar_inband_t input,
5426e13b1fa5SApple OSS Distributions mach_msg_type_number_t inputCount,
5427e13b1fa5SApple OSS Distributions io_struct_inband_t inputStruct,
5428e13b1fa5SApple OSS Distributions mach_msg_type_number_t inputStructCount )
5429e13b1fa5SApple OSS Distributions {
5430e13b1fa5SApple OSS Distributions uint32_t i;
5431e13b1fa5SApple OSS Distributions io_scalar_inband64_t _input;
5432e13b1fa5SApple OSS Distributions io_async_ref64_t _reference;
5433e13b1fa5SApple OSS Distributions
5434a5e72196SApple OSS Distributions if (referenceCnt > ASYNC_REF64_COUNT) {
5435a5e72196SApple OSS Distributions return kIOReturnBadArgument;
5436a5e72196SApple OSS Distributions }
5437a5e72196SApple OSS Distributions for (i = 0; i < referenceCnt; i++) {
5438e13b1fa5SApple OSS Distributions _reference[i] = REF64(reference[i]);
5439a5e72196SApple OSS Distributions }
5440a5e72196SApple OSS Distributions bzero(&_reference[referenceCnt], (ASYNC_REF64_COUNT - referenceCnt) * sizeof(_reference[0]));
5441e13b1fa5SApple OSS Distributions
5442e13b1fa5SApple OSS Distributions mach_msg_type_number_t scalar_outputCnt = 0;
5443e13b1fa5SApple OSS Distributions mach_msg_type_number_t inband_outputCnt = 0;
5444e13b1fa5SApple OSS Distributions mach_vm_size_t ool_output_size = 0;
5445e13b1fa5SApple OSS Distributions
5446a5e72196SApple OSS Distributions for (i = 0; i < inputCount; i++) {
5447e13b1fa5SApple OSS Distributions _input[i] = SCALAR64(input[i]);
5448a5e72196SApple OSS Distributions }
5449e13b1fa5SApple OSS Distributions
5450a5e72196SApple OSS Distributions return is_io_connect_async_method(connect,
5451e13b1fa5SApple OSS Distributions wake_port, _reference, referenceCnt,
5452e13b1fa5SApple OSS Distributions index,
5453e13b1fa5SApple OSS Distributions _input, inputCount,
5454e13b1fa5SApple OSS Distributions inputStruct, inputStructCount,
5455e13b1fa5SApple OSS Distributions 0, 0,
5456e13b1fa5SApple OSS Distributions NULL, &inband_outputCnt,
5457855239e5SApple OSS Distributions NULL, &scalar_outputCnt,
5458a5e72196SApple OSS Distributions 0, &ool_output_size);
5459e13b1fa5SApple OSS Distributions }
5460e13b1fa5SApple OSS Distributions
5461e13b1fa5SApple OSS Distributions /* Routine io_async_method_structureI_structureO */
5462a5e72196SApple OSS Distributions kern_return_t
is_io_async_method_structureI_structureO(io_object_t connect,mach_port_t wake_port,io_async_ref_t reference,mach_msg_type_number_t referenceCnt,uint32_t index,io_struct_inband_t input,mach_msg_type_number_t inputCount,io_struct_inband_t output,mach_msg_type_number_t * outputCount)5463a5e72196SApple OSS Distributions is_io_async_method_structureI_structureO(
5464e13b1fa5SApple OSS Distributions io_object_t connect,
5465e13b1fa5SApple OSS Distributions mach_port_t wake_port,
5466e13b1fa5SApple OSS Distributions io_async_ref_t reference,
5467e13b1fa5SApple OSS Distributions mach_msg_type_number_t referenceCnt,
5468e13b1fa5SApple OSS Distributions uint32_t index,
5469e13b1fa5SApple OSS Distributions io_struct_inband_t input,
5470e13b1fa5SApple OSS Distributions mach_msg_type_number_t inputCount,
5471e13b1fa5SApple OSS Distributions io_struct_inband_t output,
5472e13b1fa5SApple OSS Distributions mach_msg_type_number_t * outputCount )
5473e13b1fa5SApple OSS Distributions {
5474e13b1fa5SApple OSS Distributions uint32_t i;
5475e13b1fa5SApple OSS Distributions mach_msg_type_number_t scalar_outputCnt = 0;
5476e13b1fa5SApple OSS Distributions mach_vm_size_t ool_output_size = 0;
5477e13b1fa5SApple OSS Distributions io_async_ref64_t _reference;
5478e13b1fa5SApple OSS Distributions
5479a5e72196SApple OSS Distributions if (referenceCnt > ASYNC_REF64_COUNT) {
5480a5e72196SApple OSS Distributions return kIOReturnBadArgument;
5481a5e72196SApple OSS Distributions }
5482a5e72196SApple OSS Distributions for (i = 0; i < referenceCnt; i++) {
5483e13b1fa5SApple OSS Distributions _reference[i] = REF64(reference[i]);
5484a5e72196SApple OSS Distributions }
5485a5e72196SApple OSS Distributions bzero(&_reference[referenceCnt], (ASYNC_REF64_COUNT - referenceCnt) * sizeof(_reference[0]));
5486e13b1fa5SApple OSS Distributions
5487a5e72196SApple OSS Distributions return is_io_connect_async_method(connect,
5488e13b1fa5SApple OSS Distributions wake_port, _reference, referenceCnt,
5489e13b1fa5SApple OSS Distributions index,
5490e13b1fa5SApple OSS Distributions NULL, 0,
5491e13b1fa5SApple OSS Distributions input, inputCount,
5492e13b1fa5SApple OSS Distributions 0, 0,
5493e13b1fa5SApple OSS Distributions output, outputCount,
5494855239e5SApple OSS Distributions NULL, &scalar_outputCnt,
5495a5e72196SApple OSS Distributions 0, &ool_output_size);
5496e13b1fa5SApple OSS Distributions }
5497e13b1fa5SApple OSS Distributions
5498e13b1fa5SApple OSS Distributions
5499a5e72196SApple OSS Distributions kern_return_t
shim_io_async_method_scalarI_scalarO(IOExternalAsyncMethod * method,IOService * object,mach_port_t asyncWakePort,io_user_reference_t * asyncReference,uint32_t asyncReferenceCount,const io_user_scalar_t * input,mach_msg_type_number_t inputCount,io_user_scalar_t * output,mach_msg_type_number_t * outputCount)5500a5e72196SApple OSS Distributions shim_io_async_method_scalarI_scalarO(
5501e13b1fa5SApple OSS Distributions IOExternalAsyncMethod * method,
5502e13b1fa5SApple OSS Distributions IOService * object,
5503e13b1fa5SApple OSS Distributions mach_port_t asyncWakePort,
5504e13b1fa5SApple OSS Distributions io_user_reference_t * asyncReference,
5505e13b1fa5SApple OSS Distributions uint32_t asyncReferenceCount,
5506e13b1fa5SApple OSS Distributions const io_user_scalar_t * input,
5507e13b1fa5SApple OSS Distributions mach_msg_type_number_t inputCount,
5508e13b1fa5SApple OSS Distributions io_user_scalar_t * output,
5509e13b1fa5SApple OSS Distributions mach_msg_type_number_t * outputCount )
5510e13b1fa5SApple OSS Distributions {
5511e13b1fa5SApple OSS Distributions IOAsyncMethod func;
5512e13b1fa5SApple OSS Distributions uint32_t i;
5513e13b1fa5SApple OSS Distributions io_scalar_inband_t _output;
5514e13b1fa5SApple OSS Distributions IOReturn err;
5515e13b1fa5SApple OSS Distributions io_async_ref_t reference;
5516e13b1fa5SApple OSS Distributions
5517a3bb9fccSApple OSS Distributions bzero(&_output[0], sizeof(_output));
5518a5e72196SApple OSS Distributions for (i = 0; i < asyncReferenceCount; i++) {
5519e13b1fa5SApple OSS Distributions reference[i] = REF32(asyncReference[i]);
5520a5e72196SApple OSS Distributions }
5521e13b1fa5SApple OSS Distributions
5522e13b1fa5SApple OSS Distributions err = kIOReturnBadArgument;
5523e13b1fa5SApple OSS Distributions
5524e13b1fa5SApple OSS Distributions do {
5525a5e72196SApple OSS Distributions if (inputCount != method->count0) {
552688cc0b97SApple OSS Distributions IOLog("%s:%d %s: IOUserClient inputCount count mismatch 0x%llx 0x%llx\n", __FUNCTION__, __LINE__, object->getName(), (uint64_t)inputCount, (uint64_t)method->count0);
552788cc0b97SApple OSS Distributions DTRACE_IO2(iokit_count_mismatch, uint64_t, (uint64_t)inputCount, uint64_t, (uint64_t)method->count0);
5528e13b1fa5SApple OSS Distributions continue;
5529e13b1fa5SApple OSS Distributions }
5530a5e72196SApple OSS Distributions if (*outputCount != method->count1) {
553188cc0b97SApple OSS Distributions IOLog("%s:%d %s: IOUserClient outputCount count mismatch 0x%llx 0x%llx\n", __FUNCTION__, __LINE__, object->getName(), (uint64_t)*outputCount, (uint64_t)method->count1);
553288cc0b97SApple OSS Distributions DTRACE_IO2(iokit_count_mismatch, uint64_t, (uint64_t)*outputCount, uint64_t, (uint64_t)method->count1);
5533e13b1fa5SApple OSS Distributions continue;
5534e13b1fa5SApple OSS Distributions }
5535e13b1fa5SApple OSS Distributions
5536e13b1fa5SApple OSS Distributions func = method->func;
5537e13b1fa5SApple OSS Distributions
5538e13b1fa5SApple OSS Distributions switch (inputCount) {
5539e13b1fa5SApple OSS Distributions case 6:
5540e13b1fa5SApple OSS Distributions err = (object->*func)( reference,
5541e13b1fa5SApple OSS Distributions ARG32(input[0]), ARG32(input[1]), ARG32(input[2]),
5542e13b1fa5SApple OSS Distributions ARG32(input[3]), ARG32(input[4]), ARG32(input[5]));
5543e13b1fa5SApple OSS Distributions break;
5544e13b1fa5SApple OSS Distributions case 5:
5545e13b1fa5SApple OSS Distributions err = (object->*func)( reference,
5546e13b1fa5SApple OSS Distributions ARG32(input[0]), ARG32(input[1]), ARG32(input[2]),
5547e13b1fa5SApple OSS Distributions ARG32(input[3]), ARG32(input[4]),
5548e13b1fa5SApple OSS Distributions &_output[0] );
5549e13b1fa5SApple OSS Distributions break;
5550e13b1fa5SApple OSS Distributions case 4:
5551e13b1fa5SApple OSS Distributions err = (object->*func)( reference,
5552e13b1fa5SApple OSS Distributions ARG32(input[0]), ARG32(input[1]), ARG32(input[2]),
5553e13b1fa5SApple OSS Distributions ARG32(input[3]),
5554e13b1fa5SApple OSS Distributions &_output[0], &_output[1] );
5555e13b1fa5SApple OSS Distributions break;
5556e13b1fa5SApple OSS Distributions case 3:
5557e13b1fa5SApple OSS Distributions err = (object->*func)( reference,
5558e13b1fa5SApple OSS Distributions ARG32(input[0]), ARG32(input[1]), ARG32(input[2]),
5559e13b1fa5SApple OSS Distributions &_output[0], &_output[1], &_output[2] );
5560e13b1fa5SApple OSS Distributions break;
5561e13b1fa5SApple OSS Distributions case 2:
5562e13b1fa5SApple OSS Distributions err = (object->*func)( reference,
5563e13b1fa5SApple OSS Distributions ARG32(input[0]), ARG32(input[1]),
5564e13b1fa5SApple OSS Distributions &_output[0], &_output[1], &_output[2],
5565e13b1fa5SApple OSS Distributions &_output[3] );
5566e13b1fa5SApple OSS Distributions break;
5567e13b1fa5SApple OSS Distributions case 1:
5568e13b1fa5SApple OSS Distributions err = (object->*func)( reference,
5569e13b1fa5SApple OSS Distributions ARG32(input[0]),
5570e13b1fa5SApple OSS Distributions &_output[0], &_output[1], &_output[2],
5571e13b1fa5SApple OSS Distributions &_output[3], &_output[4] );
5572e13b1fa5SApple OSS Distributions break;
5573e13b1fa5SApple OSS Distributions case 0:
5574e13b1fa5SApple OSS Distributions err = (object->*func)( reference,
5575e13b1fa5SApple OSS Distributions &_output[0], &_output[1], &_output[2],
5576e13b1fa5SApple OSS Distributions &_output[3], &_output[4], &_output[5] );
5577e13b1fa5SApple OSS Distributions break;
5578e13b1fa5SApple OSS Distributions
5579e13b1fa5SApple OSS Distributions default:
5580e13b1fa5SApple OSS Distributions IOLog("%s: Bad method table\n", object->getName());
5581e13b1fa5SApple OSS Distributions }
5582a5e72196SApple OSS Distributions }while (false);
5583e13b1fa5SApple OSS Distributions
5584a5e72196SApple OSS Distributions for (i = 0; i < *outputCount; i++) {
5585e13b1fa5SApple OSS Distributions output[i] = SCALAR32(_output[i]);
5586a5e72196SApple OSS Distributions }
5587e13b1fa5SApple OSS Distributions
5588a5e72196SApple OSS Distributions return err;
5589e13b1fa5SApple OSS Distributions }
5590e13b1fa5SApple OSS Distributions
5591e13b1fa5SApple OSS Distributions
5592c1dac77fSApple OSS Distributions /* Routine io_connect_method_scalarI_structureO */
5593a5e72196SApple OSS Distributions kern_return_t
is_io_connect_method_scalarI_structureO(io_object_t connect,uint32_t index,io_scalar_inband_t input,mach_msg_type_number_t inputCount,io_struct_inband_t output,mach_msg_type_number_t * outputCount)5594a5e72196SApple OSS Distributions is_io_connect_method_scalarI_structureO(
5595c1dac77fSApple OSS Distributions io_object_t connect,
5596e13b1fa5SApple OSS Distributions uint32_t index,
5597e13b1fa5SApple OSS Distributions io_scalar_inband_t input,
5598e13b1fa5SApple OSS Distributions mach_msg_type_number_t inputCount,
5599e13b1fa5SApple OSS Distributions io_struct_inband_t output,
5600e13b1fa5SApple OSS Distributions mach_msg_type_number_t * outputCount )
5601c1dac77fSApple OSS Distributions {
5602e13b1fa5SApple OSS Distributions uint32_t i;
5603e13b1fa5SApple OSS Distributions io_scalar_inband64_t _input;
5604e13b1fa5SApple OSS Distributions
5605e13b1fa5SApple OSS Distributions mach_msg_type_number_t scalar_outputCnt = 0;
5606e13b1fa5SApple OSS Distributions mach_vm_size_t ool_output_size = 0;
5607e13b1fa5SApple OSS Distributions
5608a5e72196SApple OSS Distributions for (i = 0; i < inputCount; i++) {
5609e13b1fa5SApple OSS Distributions _input[i] = SCALAR64(input[i]);
5610a5e72196SApple OSS Distributions }
5611e13b1fa5SApple OSS Distributions
5612a5e72196SApple OSS Distributions return is_io_connect_method(connect, index,
5613e13b1fa5SApple OSS Distributions _input, inputCount,
5614e13b1fa5SApple OSS Distributions NULL, 0,
5615e13b1fa5SApple OSS Distributions 0, 0,
5616e13b1fa5SApple OSS Distributions output, outputCount,
5617855239e5SApple OSS Distributions NULL, &scalar_outputCnt,
5618a5e72196SApple OSS Distributions 0, &ool_output_size);
5619e13b1fa5SApple OSS Distributions }
5620e13b1fa5SApple OSS Distributions
5621a5e72196SApple OSS Distributions kern_return_t
shim_io_connect_method_scalarI_structureO(IOExternalMethod * method,IOService * object,const io_user_scalar_t * input,mach_msg_type_number_t inputCount,io_struct_inband_t output,IOByteCount * outputCount)5622a5e72196SApple OSS Distributions shim_io_connect_method_scalarI_structureO(
5623e13b1fa5SApple OSS Distributions
5624e13b1fa5SApple OSS Distributions IOExternalMethod * method,
5625e13b1fa5SApple OSS Distributions IOService * object,
5626e13b1fa5SApple OSS Distributions const io_user_scalar_t * input,
5627e13b1fa5SApple OSS Distributions mach_msg_type_number_t inputCount,
5628e13b1fa5SApple OSS Distributions io_struct_inband_t output,
56293ca3bd55SApple OSS Distributions IOByteCount * outputCount )
5630e13b1fa5SApple OSS Distributions {
5631c1dac77fSApple OSS Distributions IOMethod func;
5632e13b1fa5SApple OSS Distributions IOReturn err;
5633c1dac77fSApple OSS Distributions
5634c1dac77fSApple OSS Distributions err = kIOReturnBadArgument;
5635e13b1fa5SApple OSS Distributions
5636e13b1fa5SApple OSS Distributions do {
5637a5e72196SApple OSS Distributions if (inputCount != method->count0) {
563888cc0b97SApple OSS Distributions IOLog("%s:%d %s: IOUserClient inputCount count mismatch 0x%llx 0x%llx\n", __FUNCTION__, __LINE__, object->getName(), (uint64_t)inputCount, (uint64_t)method->count0);
563988cc0b97SApple OSS Distributions DTRACE_IO2(iokit_count_mismatch, uint64_t, (uint64_t)inputCount, uint64_t, (uint64_t)method->count0);
5640c1dac77fSApple OSS Distributions continue;
5641e13b1fa5SApple OSS Distributions }
5642e13b1fa5SApple OSS Distributions if ((kIOUCVariableStructureSize != method->count1)
5643a5e72196SApple OSS Distributions && (*outputCount != method->count1)) {
564488cc0b97SApple OSS Distributions IOLog("%s:%d %s: IOUserClient outputCount count mismatch 0x%llx 0x%llx 0x%llx\n", __FUNCTION__, __LINE__, object->getName(), (uint64_t)*outputCount, (uint64_t)method->count1, (uint64_t)kIOUCVariableStructureSize);
564588cc0b97SApple OSS Distributions DTRACE_IO2(iokit_count_mismatch, uint64_t, (uint64_t)*outputCount, uint64_t, (uint64_t)method->count1);
5646c1dac77fSApple OSS Distributions continue;
5647e13b1fa5SApple OSS Distributions }
5648c1dac77fSApple OSS Distributions
5649c1dac77fSApple OSS Distributions func = method->func;
5650c1dac77fSApple OSS Distributions
5651c1dac77fSApple OSS Distributions switch (inputCount) {
5652c1dac77fSApple OSS Distributions case 5:
5653e13b1fa5SApple OSS Distributions err = (object->*func)( ARG32(input[0]), ARG32(input[1]), ARG32(input[2]),
5654e13b1fa5SApple OSS Distributions ARG32(input[3]), ARG32(input[4]),
5655c1dac77fSApple OSS Distributions output );
5656c1dac77fSApple OSS Distributions break;
5657c1dac77fSApple OSS Distributions case 4:
5658e13b1fa5SApple OSS Distributions err = (object->*func)( ARG32(input[0]), ARG32(input[1]), ARG32(input[2]),
5659e13b1fa5SApple OSS Distributions ARG32(input[3]),
5660c1dac77fSApple OSS Distributions output, (void *)outputCount );
5661c1dac77fSApple OSS Distributions break;
5662c1dac77fSApple OSS Distributions case 3:
5663e13b1fa5SApple OSS Distributions err = (object->*func)( ARG32(input[0]), ARG32(input[1]), ARG32(input[2]),
5664a5e72196SApple OSS Distributions output, (void *)outputCount, NULL );
5665c1dac77fSApple OSS Distributions break;
5666c1dac77fSApple OSS Distributions case 2:
5667e13b1fa5SApple OSS Distributions err = (object->*func)( ARG32(input[0]), ARG32(input[1]),
5668a5e72196SApple OSS Distributions output, (void *)outputCount, NULL, NULL );
5669c1dac77fSApple OSS Distributions break;
5670c1dac77fSApple OSS Distributions case 1:
5671e13b1fa5SApple OSS Distributions err = (object->*func)( ARG32(input[0]),
5672a5e72196SApple OSS Distributions output, (void *)outputCount, NULL, NULL, NULL );
5673c1dac77fSApple OSS Distributions break;
5674c1dac77fSApple OSS Distributions case 0:
5675a5e72196SApple OSS Distributions err = (object->*func)( output, (void *)outputCount, NULL, NULL, NULL, NULL );
5676c1dac77fSApple OSS Distributions break;
5677c1dac77fSApple OSS Distributions
5678c1dac77fSApple OSS Distributions default:
5679e13b1fa5SApple OSS Distributions IOLog("%s: Bad method table\n", object->getName());
5680c1dac77fSApple OSS Distributions }
5681a5e72196SApple OSS Distributions }while (false);
5682c1dac77fSApple OSS Distributions
5683a5e72196SApple OSS Distributions return err;
5684e13b1fa5SApple OSS Distributions }
5685e13b1fa5SApple OSS Distributions
5686e13b1fa5SApple OSS Distributions
5687a5e72196SApple OSS Distributions kern_return_t
shim_io_async_method_scalarI_structureO(IOExternalAsyncMethod * method,IOService * object,mach_port_t asyncWakePort,io_user_reference_t * asyncReference,uint32_t asyncReferenceCount,const io_user_scalar_t * input,mach_msg_type_number_t inputCount,io_struct_inband_t output,mach_msg_type_number_t * outputCount)5688a5e72196SApple OSS Distributions shim_io_async_method_scalarI_structureO(
5689e13b1fa5SApple OSS Distributions IOExternalAsyncMethod * method,
5690e13b1fa5SApple OSS Distributions IOService * object,
5691e13b1fa5SApple OSS Distributions mach_port_t asyncWakePort,
5692e13b1fa5SApple OSS Distributions io_user_reference_t * asyncReference,
5693e13b1fa5SApple OSS Distributions uint32_t asyncReferenceCount,
5694e13b1fa5SApple OSS Distributions const io_user_scalar_t * input,
5695e13b1fa5SApple OSS Distributions mach_msg_type_number_t inputCount,
5696e13b1fa5SApple OSS Distributions io_struct_inband_t output,
5697e13b1fa5SApple OSS Distributions mach_msg_type_number_t * outputCount )
5698e13b1fa5SApple OSS Distributions {
5699e13b1fa5SApple OSS Distributions IOAsyncMethod func;
5700e13b1fa5SApple OSS Distributions uint32_t i;
5701e13b1fa5SApple OSS Distributions IOReturn err;
5702e13b1fa5SApple OSS Distributions io_async_ref_t reference;
5703e13b1fa5SApple OSS Distributions
5704a5e72196SApple OSS Distributions for (i = 0; i < asyncReferenceCount; i++) {
5705e13b1fa5SApple OSS Distributions reference[i] = REF32(asyncReference[i]);
5706a5e72196SApple OSS Distributions }
5707e13b1fa5SApple OSS Distributions
5708e13b1fa5SApple OSS Distributions err = kIOReturnBadArgument;
5709e13b1fa5SApple OSS Distributions do {
5710a5e72196SApple OSS Distributions if (inputCount != method->count0) {
571188cc0b97SApple OSS Distributions IOLog("%s:%d %s: IOUserClient inputCount count mismatch 0x%llx 0x%llx\n", __FUNCTION__, __LINE__, object->getName(), (uint64_t)inputCount, (uint64_t)method->count0);
571288cc0b97SApple OSS Distributions DTRACE_IO2(iokit_count_mismatch, uint64_t, (uint64_t)inputCount, uint64_t, (uint64_t)method->count0);
5713e13b1fa5SApple OSS Distributions continue;
5714e13b1fa5SApple OSS Distributions }
5715e13b1fa5SApple OSS Distributions if ((kIOUCVariableStructureSize != method->count1)
5716a5e72196SApple OSS Distributions && (*outputCount != method->count1)) {
571788cc0b97SApple OSS Distributions IOLog("%s:%d %s: IOUserClient outputCount count mismatch 0x%llx 0x%llx 0x%llx\n", __FUNCTION__, __LINE__, object->getName(), (uint64_t)*outputCount, (uint64_t)method->count1, (uint64_t)kIOUCVariableStructureSize);
571888cc0b97SApple OSS Distributions DTRACE_IO2(iokit_count_mismatch, uint64_t, (uint64_t)*outputCount, uint64_t, (uint64_t)method->count1);
5719e13b1fa5SApple OSS Distributions continue;
5720e13b1fa5SApple OSS Distributions }
5721e13b1fa5SApple OSS Distributions
5722e13b1fa5SApple OSS Distributions func = method->func;
5723e13b1fa5SApple OSS Distributions
5724e13b1fa5SApple OSS Distributions switch (inputCount) {
5725e13b1fa5SApple OSS Distributions case 5:
5726e13b1fa5SApple OSS Distributions err = (object->*func)( reference,
5727e13b1fa5SApple OSS Distributions ARG32(input[0]), ARG32(input[1]), ARG32(input[2]),
5728e13b1fa5SApple OSS Distributions ARG32(input[3]), ARG32(input[4]),
5729e13b1fa5SApple OSS Distributions output );
5730e13b1fa5SApple OSS Distributions break;
5731e13b1fa5SApple OSS Distributions case 4:
5732e13b1fa5SApple OSS Distributions err = (object->*func)( reference,
5733e13b1fa5SApple OSS Distributions ARG32(input[0]), ARG32(input[1]), ARG32(input[2]),
5734e13b1fa5SApple OSS Distributions ARG32(input[3]),
5735e13b1fa5SApple OSS Distributions output, (void *)outputCount );
5736e13b1fa5SApple OSS Distributions break;
5737e13b1fa5SApple OSS Distributions case 3:
5738e13b1fa5SApple OSS Distributions err = (object->*func)( reference,
5739e13b1fa5SApple OSS Distributions ARG32(input[0]), ARG32(input[1]), ARG32(input[2]),
5740a5e72196SApple OSS Distributions output, (void *)outputCount, NULL );
5741e13b1fa5SApple OSS Distributions break;
5742e13b1fa5SApple OSS Distributions case 2:
5743e13b1fa5SApple OSS Distributions err = (object->*func)( reference,
5744e13b1fa5SApple OSS Distributions ARG32(input[0]), ARG32(input[1]),
5745a5e72196SApple OSS Distributions output, (void *)outputCount, NULL, NULL );
5746e13b1fa5SApple OSS Distributions break;
5747e13b1fa5SApple OSS Distributions case 1:
5748e13b1fa5SApple OSS Distributions err = (object->*func)( reference,
5749e13b1fa5SApple OSS Distributions ARG32(input[0]),
5750a5e72196SApple OSS Distributions output, (void *)outputCount, NULL, NULL, NULL );
5751e13b1fa5SApple OSS Distributions break;
5752e13b1fa5SApple OSS Distributions case 0:
5753e13b1fa5SApple OSS Distributions err = (object->*func)( reference,
5754a5e72196SApple OSS Distributions output, (void *)outputCount, NULL, NULL, NULL, NULL );
5755e13b1fa5SApple OSS Distributions break;
5756e13b1fa5SApple OSS Distributions
5757e13b1fa5SApple OSS Distributions default:
5758e13b1fa5SApple OSS Distributions IOLog("%s: Bad method table\n", object->getName());
5759e13b1fa5SApple OSS Distributions }
5760a5e72196SApple OSS Distributions }while (false);
5761c1dac77fSApple OSS Distributions
5762a5e72196SApple OSS Distributions return err;
5763c1dac77fSApple OSS Distributions }
5764c1dac77fSApple OSS Distributions
5765c1dac77fSApple OSS Distributions /* Routine io_connect_method_scalarI_structureI */
5766a5e72196SApple OSS Distributions kern_return_t
is_io_connect_method_scalarI_structureI(io_connect_t connect,uint32_t index,io_scalar_inband_t input,mach_msg_type_number_t inputCount,io_struct_inband_t inputStruct,mach_msg_type_number_t inputStructCount)5767a5e72196SApple OSS Distributions is_io_connect_method_scalarI_structureI(
5768c1dac77fSApple OSS Distributions io_connect_t connect,
5769e13b1fa5SApple OSS Distributions uint32_t index,
5770e13b1fa5SApple OSS Distributions io_scalar_inband_t input,
5771e13b1fa5SApple OSS Distributions mach_msg_type_number_t inputCount,
5772e13b1fa5SApple OSS Distributions io_struct_inband_t inputStruct,
5773e13b1fa5SApple OSS Distributions mach_msg_type_number_t inputStructCount )
5774c1dac77fSApple OSS Distributions {
5775e13b1fa5SApple OSS Distributions uint32_t i;
5776e13b1fa5SApple OSS Distributions io_scalar_inband64_t _input;
5777e13b1fa5SApple OSS Distributions
5778e13b1fa5SApple OSS Distributions mach_msg_type_number_t scalar_outputCnt = 0;
5779e13b1fa5SApple OSS Distributions mach_msg_type_number_t inband_outputCnt = 0;
5780e13b1fa5SApple OSS Distributions mach_vm_size_t ool_output_size = 0;
5781e13b1fa5SApple OSS Distributions
5782a5e72196SApple OSS Distributions for (i = 0; i < inputCount; i++) {
5783e13b1fa5SApple OSS Distributions _input[i] = SCALAR64(input[i]);
5784a5e72196SApple OSS Distributions }
5785e13b1fa5SApple OSS Distributions
5786a5e72196SApple OSS Distributions return is_io_connect_method(connect, index,
5787e13b1fa5SApple OSS Distributions _input, inputCount,
5788e13b1fa5SApple OSS Distributions inputStruct, inputStructCount,
5789e13b1fa5SApple OSS Distributions 0, 0,
5790e13b1fa5SApple OSS Distributions NULL, &inband_outputCnt,
5791855239e5SApple OSS Distributions NULL, &scalar_outputCnt,
5792a5e72196SApple OSS Distributions 0, &ool_output_size);
5793e13b1fa5SApple OSS Distributions }
5794e13b1fa5SApple OSS Distributions
5795a5e72196SApple OSS Distributions kern_return_t
shim_io_connect_method_scalarI_structureI(IOExternalMethod * method,IOService * object,const io_user_scalar_t * input,mach_msg_type_number_t inputCount,io_struct_inband_t inputStruct,mach_msg_type_number_t inputStructCount)5796a5e72196SApple OSS Distributions shim_io_connect_method_scalarI_structureI(
5797e13b1fa5SApple OSS Distributions IOExternalMethod * method,
5798e13b1fa5SApple OSS Distributions IOService * object,
5799e13b1fa5SApple OSS Distributions const io_user_scalar_t * input,
5800e13b1fa5SApple OSS Distributions mach_msg_type_number_t inputCount,
5801e13b1fa5SApple OSS Distributions io_struct_inband_t inputStruct,
5802e13b1fa5SApple OSS Distributions mach_msg_type_number_t inputStructCount )
5803e13b1fa5SApple OSS Distributions {
5804c1dac77fSApple OSS Distributions IOMethod func;
5805e13b1fa5SApple OSS Distributions IOReturn err = kIOReturnBadArgument;
5806c1dac77fSApple OSS Distributions
5807a5e72196SApple OSS Distributions do{
5808a5e72196SApple OSS Distributions if (inputCount != method->count0) {
580988cc0b97SApple OSS Distributions IOLog("%s:%d %s: IOUserClient inputCount count mismatch 0x%llx 0x%llx\n", __FUNCTION__, __LINE__, object->getName(), (uint64_t)inputCount, (uint64_t)method->count0);
581088cc0b97SApple OSS Distributions DTRACE_IO2(iokit_count_mismatch, uint64_t, (uint64_t)inputCount, uint64_t, (uint64_t)method->count0);
5811c1dac77fSApple OSS Distributions continue;
5812e13b1fa5SApple OSS Distributions }
5813e13b1fa5SApple OSS Distributions if ((kIOUCVariableStructureSize != method->count1)
5814a5e72196SApple OSS Distributions && (inputStructCount != method->count1)) {
581588cc0b97SApple OSS Distributions IOLog("%s:%d %s: IOUserClient outputCount count mismatch 0x%llx 0x%llx 0x%llx\n", __FUNCTION__, __LINE__, object->getName(), (uint64_t)inputStructCount, (uint64_t)method->count1, (uint64_t)kIOUCVariableStructureSize);
581688cc0b97SApple OSS Distributions DTRACE_IO2(iokit_count_mismatch, uint64_t, (uint64_t)inputStructCount, uint64_t, (uint64_t)method->count1);
5817c1dac77fSApple OSS Distributions continue;
5818e13b1fa5SApple OSS Distributions }
5819c1dac77fSApple OSS Distributions
5820c1dac77fSApple OSS Distributions func = method->func;
5821c1dac77fSApple OSS Distributions
5822c1dac77fSApple OSS Distributions switch (inputCount) {
5823c1dac77fSApple OSS Distributions case 5:
5824e13b1fa5SApple OSS Distributions err = (object->*func)( ARG32(input[0]), ARG32(input[1]), ARG32(input[2]),
5825e13b1fa5SApple OSS Distributions ARG32(input[3]), ARG32(input[4]),
5826c1dac77fSApple OSS Distributions inputStruct );
5827c1dac77fSApple OSS Distributions break;
5828c1dac77fSApple OSS Distributions case 4:
5829e13b1fa5SApple OSS Distributions err = (object->*func)( ARG32(input[0]), ARG32(input[1]), (void *) input[2],
5830e13b1fa5SApple OSS Distributions ARG32(input[3]),
5831186b8fceSApple OSS Distributions inputStruct, (void *)(uintptr_t)inputStructCount );
5832c1dac77fSApple OSS Distributions break;
5833c1dac77fSApple OSS Distributions case 3:
5834e13b1fa5SApple OSS Distributions err = (object->*func)( ARG32(input[0]), ARG32(input[1]), ARG32(input[2]),
5835186b8fceSApple OSS Distributions inputStruct, (void *)(uintptr_t)inputStructCount,
5836a5e72196SApple OSS Distributions NULL );
5837c1dac77fSApple OSS Distributions break;
5838c1dac77fSApple OSS Distributions case 2:
5839e13b1fa5SApple OSS Distributions err = (object->*func)( ARG32(input[0]), ARG32(input[1]),
5840186b8fceSApple OSS Distributions inputStruct, (void *)(uintptr_t)inputStructCount,
5841a5e72196SApple OSS Distributions NULL, NULL );
5842c1dac77fSApple OSS Distributions break;
5843c1dac77fSApple OSS Distributions case 1:
5844e13b1fa5SApple OSS Distributions err = (object->*func)( ARG32(input[0]),
5845186b8fceSApple OSS Distributions inputStruct, (void *)(uintptr_t)inputStructCount,
5846a5e72196SApple OSS Distributions NULL, NULL, NULL );
5847c1dac77fSApple OSS Distributions break;
5848c1dac77fSApple OSS Distributions case 0:
5849186b8fceSApple OSS Distributions err = (object->*func)( inputStruct, (void *)(uintptr_t)inputStructCount,
5850a5e72196SApple OSS Distributions NULL, NULL, NULL, NULL );
5851c1dac77fSApple OSS Distributions break;
5852c1dac77fSApple OSS Distributions
5853c1dac77fSApple OSS Distributions default:
5854e13b1fa5SApple OSS Distributions IOLog("%s: Bad method table\n", object->getName());
5855c1dac77fSApple OSS Distributions }
5856a5e72196SApple OSS Distributions }while (false);
5857c1dac77fSApple OSS Distributions
5858a5e72196SApple OSS Distributions return err;
5859e13b1fa5SApple OSS Distributions }
5860e13b1fa5SApple OSS Distributions
5861a5e72196SApple OSS Distributions kern_return_t
shim_io_async_method_scalarI_structureI(IOExternalAsyncMethod * method,IOService * object,mach_port_t asyncWakePort,io_user_reference_t * asyncReference,uint32_t asyncReferenceCount,const io_user_scalar_t * input,mach_msg_type_number_t inputCount,io_struct_inband_t inputStruct,mach_msg_type_number_t inputStructCount)5862a5e72196SApple OSS Distributions shim_io_async_method_scalarI_structureI(
5863e13b1fa5SApple OSS Distributions IOExternalAsyncMethod * method,
5864e13b1fa5SApple OSS Distributions IOService * object,
5865e13b1fa5SApple OSS Distributions mach_port_t asyncWakePort,
5866e13b1fa5SApple OSS Distributions io_user_reference_t * asyncReference,
5867e13b1fa5SApple OSS Distributions uint32_t asyncReferenceCount,
5868e13b1fa5SApple OSS Distributions const io_user_scalar_t * input,
5869e13b1fa5SApple OSS Distributions mach_msg_type_number_t inputCount,
5870e13b1fa5SApple OSS Distributions io_struct_inband_t inputStruct,
5871e13b1fa5SApple OSS Distributions mach_msg_type_number_t inputStructCount )
5872e13b1fa5SApple OSS Distributions {
5873e13b1fa5SApple OSS Distributions IOAsyncMethod func;
5874e13b1fa5SApple OSS Distributions uint32_t i;
5875e13b1fa5SApple OSS Distributions IOReturn err = kIOReturnBadArgument;
5876e13b1fa5SApple OSS Distributions io_async_ref_t reference;
5877e13b1fa5SApple OSS Distributions
5878a5e72196SApple OSS Distributions for (i = 0; i < asyncReferenceCount; i++) {
5879e13b1fa5SApple OSS Distributions reference[i] = REF32(asyncReference[i]);
5880a5e72196SApple OSS Distributions }
5881e13b1fa5SApple OSS Distributions
5882a5e72196SApple OSS Distributions do{
5883a5e72196SApple OSS Distributions if (inputCount != method->count0) {
588488cc0b97SApple OSS Distributions IOLog("%s:%d %s: IOUserClient inputCount count mismatch 0x%llx 0x%llx\n", __FUNCTION__, __LINE__, object->getName(), (uint64_t)inputCount, (uint64_t)method->count0);
588588cc0b97SApple OSS Distributions DTRACE_IO2(iokit_count_mismatch, uint64_t, (uint64_t)inputCount, uint64_t, (uint64_t)method->count0);
5886e13b1fa5SApple OSS Distributions continue;
5887e13b1fa5SApple OSS Distributions }
5888e13b1fa5SApple OSS Distributions if ((kIOUCVariableStructureSize != method->count1)
5889a5e72196SApple OSS Distributions && (inputStructCount != method->count1)) {
589088cc0b97SApple OSS Distributions IOLog("%s:%d %s: IOUserClient outputCount count mismatch 0x%llx 0x%llx 0x%llx\n", __FUNCTION__, __LINE__, object->getName(), (uint64_t)inputStructCount, (uint64_t)method->count1, (uint64_t)kIOUCVariableStructureSize);
589188cc0b97SApple OSS Distributions DTRACE_IO2(iokit_count_mismatch, uint64_t, (uint64_t)inputStructCount, uint64_t, (uint64_t)method->count1);
5892e13b1fa5SApple OSS Distributions continue;
5893e13b1fa5SApple OSS Distributions }
5894e13b1fa5SApple OSS Distributions
5895e13b1fa5SApple OSS Distributions func = method->func;
5896e13b1fa5SApple OSS Distributions
5897e13b1fa5SApple OSS Distributions switch (inputCount) {
5898e13b1fa5SApple OSS Distributions case 5:
5899e13b1fa5SApple OSS Distributions err = (object->*func)( reference,
5900e13b1fa5SApple OSS Distributions ARG32(input[0]), ARG32(input[1]), ARG32(input[2]),
5901e13b1fa5SApple OSS Distributions ARG32(input[3]), ARG32(input[4]),
5902e13b1fa5SApple OSS Distributions inputStruct );
5903e13b1fa5SApple OSS Distributions break;
5904e13b1fa5SApple OSS Distributions case 4:
5905e13b1fa5SApple OSS Distributions err = (object->*func)( reference,
5906e13b1fa5SApple OSS Distributions ARG32(input[0]), ARG32(input[1]), ARG32(input[2]),
5907e13b1fa5SApple OSS Distributions ARG32(input[3]),
5908186b8fceSApple OSS Distributions inputStruct, (void *)(uintptr_t)inputStructCount );
5909e13b1fa5SApple OSS Distributions break;
5910e13b1fa5SApple OSS Distributions case 3:
5911e13b1fa5SApple OSS Distributions err = (object->*func)( reference,
5912e13b1fa5SApple OSS Distributions ARG32(input[0]), ARG32(input[1]), ARG32(input[2]),
5913186b8fceSApple OSS Distributions inputStruct, (void *)(uintptr_t)inputStructCount,
5914a5e72196SApple OSS Distributions NULL );
5915e13b1fa5SApple OSS Distributions break;
5916e13b1fa5SApple OSS Distributions case 2:
5917e13b1fa5SApple OSS Distributions err = (object->*func)( reference,
5918e13b1fa5SApple OSS Distributions ARG32(input[0]), ARG32(input[1]),
5919186b8fceSApple OSS Distributions inputStruct, (void *)(uintptr_t)inputStructCount,
5920a5e72196SApple OSS Distributions NULL, NULL );
5921e13b1fa5SApple OSS Distributions break;
5922e13b1fa5SApple OSS Distributions case 1:
5923e13b1fa5SApple OSS Distributions err = (object->*func)( reference,
5924e13b1fa5SApple OSS Distributions ARG32(input[0]),
5925186b8fceSApple OSS Distributions inputStruct, (void *)(uintptr_t)inputStructCount,
5926a5e72196SApple OSS Distributions NULL, NULL, NULL );
5927e13b1fa5SApple OSS Distributions break;
5928e13b1fa5SApple OSS Distributions case 0:
5929e13b1fa5SApple OSS Distributions err = (object->*func)( reference,
5930186b8fceSApple OSS Distributions inputStruct, (void *)(uintptr_t)inputStructCount,
5931a5e72196SApple OSS Distributions NULL, NULL, NULL, NULL );
5932e13b1fa5SApple OSS Distributions break;
5933e13b1fa5SApple OSS Distributions
5934e13b1fa5SApple OSS Distributions default:
5935e13b1fa5SApple OSS Distributions IOLog("%s: Bad method table\n", object->getName());
5936e13b1fa5SApple OSS Distributions }
5937a5e72196SApple OSS Distributions }while (false);
5938c1dac77fSApple OSS Distributions
5939a5e72196SApple OSS Distributions return err;
5940c1dac77fSApple OSS Distributions }
5941c1dac77fSApple OSS Distributions
5942c1dac77fSApple OSS Distributions /* Routine io_connect_method_structureI_structureO */
5943a5e72196SApple OSS Distributions kern_return_t
is_io_connect_method_structureI_structureO(io_object_t connect,uint32_t index,io_struct_inband_t input,mach_msg_type_number_t inputCount,io_struct_inband_t output,mach_msg_type_number_t * outputCount)5944a5e72196SApple OSS Distributions is_io_connect_method_structureI_structureO(
5945c1dac77fSApple OSS Distributions io_object_t connect,
5946e13b1fa5SApple OSS Distributions uint32_t index,
5947e13b1fa5SApple OSS Distributions io_struct_inband_t input,
5948e13b1fa5SApple OSS Distributions mach_msg_type_number_t inputCount,
5949e13b1fa5SApple OSS Distributions io_struct_inband_t output,
5950e13b1fa5SApple OSS Distributions mach_msg_type_number_t * outputCount )
5951c1dac77fSApple OSS Distributions {
5952e13b1fa5SApple OSS Distributions mach_msg_type_number_t scalar_outputCnt = 0;
5953e13b1fa5SApple OSS Distributions mach_vm_size_t ool_output_size = 0;
5954e13b1fa5SApple OSS Distributions
5955a5e72196SApple OSS Distributions return is_io_connect_method(connect, index,
5956e13b1fa5SApple OSS Distributions NULL, 0,
5957e13b1fa5SApple OSS Distributions input, inputCount,
5958e13b1fa5SApple OSS Distributions 0, 0,
5959e13b1fa5SApple OSS Distributions output, outputCount,
5960855239e5SApple OSS Distributions NULL, &scalar_outputCnt,
5961a5e72196SApple OSS Distributions 0, &ool_output_size);
5962e13b1fa5SApple OSS Distributions }
5963e13b1fa5SApple OSS Distributions
5964a5e72196SApple OSS Distributions kern_return_t
shim_io_connect_method_structureI_structureO(IOExternalMethod * method,IOService * object,io_struct_inband_t input,mach_msg_type_number_t inputCount,io_struct_inband_t output,IOByteCount * outputCount)5965a5e72196SApple OSS Distributions shim_io_connect_method_structureI_structureO(
5966e13b1fa5SApple OSS Distributions IOExternalMethod * method,
5967e13b1fa5SApple OSS Distributions IOService * object,
5968e13b1fa5SApple OSS Distributions io_struct_inband_t input,
5969e13b1fa5SApple OSS Distributions mach_msg_type_number_t inputCount,
5970e13b1fa5SApple OSS Distributions io_struct_inband_t output,
59713ca3bd55SApple OSS Distributions IOByteCount * outputCount )
5972e13b1fa5SApple OSS Distributions {
5973c1dac77fSApple OSS Distributions IOMethod func;
5974e13b1fa5SApple OSS Distributions IOReturn err = kIOReturnBadArgument;
5975c1dac77fSApple OSS Distributions
5976a5e72196SApple OSS Distributions do{
5977e13b1fa5SApple OSS Distributions if ((kIOUCVariableStructureSize != method->count0)
5978a5e72196SApple OSS Distributions && (inputCount != method->count0)) {
597988cc0b97SApple OSS Distributions IOLog("%s:%d %s: IOUserClient inputCount count mismatch 0x%llx 0x%llx 0x%llx\n", __FUNCTION__, __LINE__, object->getName(), (uint64_t)inputCount, (uint64_t)method->count0, (uint64_t)kIOUCVariableStructureSize);
598088cc0b97SApple OSS Distributions DTRACE_IO2(iokit_count_mismatch, uint64_t, (uint64_t)inputCount, uint64_t, (uint64_t)method->count0);
5981c1dac77fSApple OSS Distributions continue;
5982e13b1fa5SApple OSS Distributions }
5983e13b1fa5SApple OSS Distributions if ((kIOUCVariableStructureSize != method->count1)
5984a5e72196SApple OSS Distributions && (*outputCount != method->count1)) {
598588cc0b97SApple OSS Distributions IOLog("%s:%d %s: IOUserClient outputCount count mismatch 0x%llx 0x%llx 0x%llx\n", __FUNCTION__, __LINE__, object->getName(), (uint64_t)*outputCount, (uint64_t)method->count1, (uint64_t)kIOUCVariableStructureSize);
598688cc0b97SApple OSS Distributions DTRACE_IO2(iokit_count_mismatch, uint64_t, (uint64_t)*outputCount, uint64_t, (uint64_t)method->count1);
5987c1dac77fSApple OSS Distributions continue;
5988e13b1fa5SApple OSS Distributions }
5989c1dac77fSApple OSS Distributions
5990c1dac77fSApple OSS Distributions func = method->func;
5991c1dac77fSApple OSS Distributions
5992c1dac77fSApple OSS Distributions if (method->count1) {
5993c1dac77fSApple OSS Distributions if (method->count0) {
5994c1dac77fSApple OSS Distributions err = (object->*func)( input, output,
5995a5e72196SApple OSS Distributions (void *)(uintptr_t)inputCount, outputCount, NULL, NULL );
5996c1dac77fSApple OSS Distributions } else {
5997a5e72196SApple OSS Distributions err = (object->*func)( output, outputCount, NULL, NULL, NULL, NULL );
5998c1dac77fSApple OSS Distributions }
5999c1dac77fSApple OSS Distributions } else {
6000a5e72196SApple OSS Distributions err = (object->*func)( input, (void *)(uintptr_t)inputCount, NULL, NULL, NULL, NULL );
6001c1dac77fSApple OSS Distributions }
6002a5e72196SApple OSS Distributions }while (false);
6003c1dac77fSApple OSS Distributions
6004c1dac77fSApple OSS Distributions
6005a5e72196SApple OSS Distributions return err;
6006c1dac77fSApple OSS Distributions }
6007c1dac77fSApple OSS Distributions
6008a5e72196SApple OSS Distributions kern_return_t
shim_io_async_method_structureI_structureO(IOExternalAsyncMethod * method,IOService * object,mach_port_t asyncWakePort,io_user_reference_t * asyncReference,uint32_t asyncReferenceCount,io_struct_inband_t input,mach_msg_type_number_t inputCount,io_struct_inband_t output,mach_msg_type_number_t * outputCount)6009a5e72196SApple OSS Distributions shim_io_async_method_structureI_structureO(
6010e13b1fa5SApple OSS Distributions IOExternalAsyncMethod * method,
6011e13b1fa5SApple OSS Distributions IOService * object,
6012e13b1fa5SApple OSS Distributions mach_port_t asyncWakePort,
6013e13b1fa5SApple OSS Distributions io_user_reference_t * asyncReference,
6014e13b1fa5SApple OSS Distributions uint32_t asyncReferenceCount,
6015e13b1fa5SApple OSS Distributions io_struct_inband_t input,
6016e13b1fa5SApple OSS Distributions mach_msg_type_number_t inputCount,
6017e13b1fa5SApple OSS Distributions io_struct_inband_t output,
6018e13b1fa5SApple OSS Distributions mach_msg_type_number_t * outputCount )
6019c1dac77fSApple OSS Distributions {
6020c1dac77fSApple OSS Distributions IOAsyncMethod func;
6021e13b1fa5SApple OSS Distributions uint32_t i;
6022e13b1fa5SApple OSS Distributions IOReturn err;
6023e13b1fa5SApple OSS Distributions io_async_ref_t reference;
6024c1dac77fSApple OSS Distributions
6025a5e72196SApple OSS Distributions for (i = 0; i < asyncReferenceCount; i++) {
6026e13b1fa5SApple OSS Distributions reference[i] = REF32(asyncReference[i]);
6027a5e72196SApple OSS Distributions }
6028e13b1fa5SApple OSS Distributions
6029c1dac77fSApple OSS Distributions err = kIOReturnBadArgument;
6030a5e72196SApple OSS Distributions do{
6031e13b1fa5SApple OSS Distributions if ((kIOUCVariableStructureSize != method->count0)
6032a5e72196SApple OSS Distributions && (inputCount != method->count0)) {
603388cc0b97SApple OSS Distributions IOLog("%s:%d %s: IOUserClient inputCount count mismatch 0x%llx 0x%llx 0x%llx\n", __FUNCTION__, __LINE__, object->getName(), (uint64_t)inputCount, (uint64_t)method->count0, (uint64_t)kIOUCVariableStructureSize);
603488cc0b97SApple OSS Distributions DTRACE_IO2(iokit_count_mismatch, uint64_t, (uint64_t)inputCount, uint64_t, (uint64_t)method->count0);
6035c1dac77fSApple OSS Distributions continue;
6036e13b1fa5SApple OSS Distributions }
6037e13b1fa5SApple OSS Distributions if ((kIOUCVariableStructureSize != method->count1)
6038a5e72196SApple OSS Distributions && (*outputCount != method->count1)) {
603988cc0b97SApple OSS Distributions IOLog("%s:%d %s: IOUserClient outputCount count mismatch 0x%llx 0x%llx 0x%llx\n", __FUNCTION__, __LINE__, object->getName(), (uint64_t)*outputCount, (uint64_t)method->count1, (uint64_t)kIOUCVariableStructureSize);
604088cc0b97SApple OSS Distributions DTRACE_IO2(iokit_count_mismatch, uint64_t, (uint64_t)*outputCount, uint64_t, (uint64_t)method->count1);
6041c1dac77fSApple OSS Distributions continue;
6042e13b1fa5SApple OSS Distributions }
6043c1dac77fSApple OSS Distributions
6044c1dac77fSApple OSS Distributions func = method->func;
6045c1dac77fSApple OSS Distributions
6046c1dac77fSApple OSS Distributions if (method->count1) {
6047c1dac77fSApple OSS Distributions if (method->count0) {
6048c1dac77fSApple OSS Distributions err = (object->*func)( reference,
6049c1dac77fSApple OSS Distributions input, output,
6050a5e72196SApple OSS Distributions (void *)(uintptr_t)inputCount, outputCount, NULL, NULL );
6051c1dac77fSApple OSS Distributions } else {
6052c1dac77fSApple OSS Distributions err = (object->*func)( reference,
6053a5e72196SApple OSS Distributions output, outputCount, NULL, NULL, NULL, NULL );
6054c1dac77fSApple OSS Distributions }
6055c1dac77fSApple OSS Distributions } else {
6056c1dac77fSApple OSS Distributions err = (object->*func)( reference,
6057a5e72196SApple OSS Distributions input, (void *)(uintptr_t)inputCount, NULL, NULL, NULL, NULL );
6058c1dac77fSApple OSS Distributions }
6059a5e72196SApple OSS Distributions }while (false);
6060c1dac77fSApple OSS Distributions
6061a5e72196SApple OSS Distributions return err;
6062c1dac77fSApple OSS Distributions }
6063e13b1fa5SApple OSS Distributions
6064c1dac77fSApple OSS Distributions /* Routine io_catalog_send_data */
6065a5e72196SApple OSS Distributions kern_return_t
is_io_catalog_send_data(mach_port_t main_port,uint32_t flag,io_buf_ptr_t inData,mach_msg_type_number_t inDataCount,kern_return_t * result)6066a5e72196SApple OSS Distributions is_io_catalog_send_data(
60675c2921b0SApple OSS Distributions mach_port_t main_port,
6068e13b1fa5SApple OSS Distributions uint32_t flag,
6069c1dac77fSApple OSS Distributions io_buf_ptr_t inData,
6070c1dac77fSApple OSS Distributions mach_msg_type_number_t inDataCount,
6071e13b1fa5SApple OSS Distributions kern_return_t * result)
6072c1dac77fSApple OSS Distributions {
6073e6231be0SApple OSS Distributions // Allow sending catalog data if there is no kextd and the kernel is DEVELOPMENT || DEBUG
6074e6231be0SApple OSS Distributions #if NO_KEXTD && !(DEVELOPMENT || DEBUG)
607576e12aa3SApple OSS Distributions return kIOReturnNotPrivileged;
6076e6231be0SApple OSS Distributions #else /* NO_KEXTD && !(DEVELOPMENT || DEBUG) */
6077a5e72196SApple OSS Distributions OSObject * obj = NULL;
6078c1dac77fSApple OSS Distributions vm_offset_t data;
6079c1dac77fSApple OSS Distributions kern_return_t kr = kIOReturnError;
6080c1dac77fSApple OSS Distributions
6081c1dac77fSApple OSS Distributions //printf("io_catalog_send_data called. flag: %d\n", flag);
6082c1dac77fSApple OSS Distributions
60835c2921b0SApple OSS Distributions if (main_port != main_device_port) {
6084c1dac77fSApple OSS Distributions return kIOReturnNotPrivileged;
6085a5e72196SApple OSS Distributions }
6086c1dac77fSApple OSS Distributions
6087a5e72196SApple OSS Distributions if ((flag != kIOCatalogRemoveKernelLinker__Removed &&
60883ca3bd55SApple OSS Distributions flag != kIOCatalogKextdActive &&
60893ca3bd55SApple OSS Distributions flag != kIOCatalogKextdFinishedLaunching) &&
6090a5e72196SApple OSS Distributions (!inData || !inDataCount)) {
6091c1dac77fSApple OSS Distributions return kIOReturnBadArgument;
60923ca3bd55SApple OSS Distributions }
6093c1dac77fSApple OSS Distributions
6094e6231be0SApple OSS Distributions if (!IOCurrentTaskHasEntitlement(kIOCatalogManagementEntitlement)) {
609576e12aa3SApple OSS Distributions OSString * taskName = IOCopyLogNameForPID(proc_selfpid());
609676e12aa3SApple OSS Distributions IOLog("IOCatalogueSendData(%s): Not entitled\n", taskName ? taskName->getCStringNoCopy() : "");
609776e12aa3SApple OSS Distributions OSSafeReleaseNULL(taskName);
609876e12aa3SApple OSS Distributions // For now, fake success to not break applications relying on this function succeeding.
609976e12aa3SApple OSS Distributions // See <rdar://problem/32554970> for more details.
610076e12aa3SApple OSS Distributions return kIOReturnSuccess;
610176e12aa3SApple OSS Distributions }
610276e12aa3SApple OSS Distributions
610314e3d835SApple OSS Distributions if (inData) {
610414e3d835SApple OSS Distributions vm_map_offset_t map_data;
610514e3d835SApple OSS Distributions
6106a5e72196SApple OSS Distributions if (inDataCount > sizeof(io_struct_inband_t) * 1024) {
6107a5e72196SApple OSS Distributions return kIOReturnMessageTooLarge;
6108a5e72196SApple OSS Distributions }
6109186b8fceSApple OSS Distributions
611014e3d835SApple OSS Distributions kr = vm_map_copyout( kernel_map, &map_data, (vm_map_copy_t)inData);
611114e3d835SApple OSS Distributions data = CAST_DOWN(vm_offset_t, map_data);
611214e3d835SApple OSS Distributions
6113a5e72196SApple OSS Distributions if (kr != KERN_SUCCESS) {
6114c1dac77fSApple OSS Distributions return kr;
6115a5e72196SApple OSS Distributions }
6116c1dac77fSApple OSS Distributions
6117c1dac77fSApple OSS Distributions // must return success after vm_map_copyout() succeeds
6118c1dac77fSApple OSS Distributions
6119c1dac77fSApple OSS Distributions if (inDataCount) {
6120186b8fceSApple OSS Distributions obj = (OSObject *)OSUnserializeXML((const char *)data, inDataCount);
6121c1dac77fSApple OSS Distributions vm_deallocate( kernel_map, data, inDataCount );
6122c1dac77fSApple OSS Distributions if (!obj) {
6123c1dac77fSApple OSS Distributions *result = kIOReturnNoMemory;
6124a5e72196SApple OSS Distributions return KERN_SUCCESS;
6125c1dac77fSApple OSS Distributions }
6126c1dac77fSApple OSS Distributions }
6127c1dac77fSApple OSS Distributions }
6128c1dac77fSApple OSS Distributions
6129c1dac77fSApple OSS Distributions switch (flag) {
6130855239e5SApple OSS Distributions case kIOCatalogResetDrivers:
6131855239e5SApple OSS Distributions case kIOCatalogResetDriversNoMatch: {
6132855239e5SApple OSS Distributions OSArray * array;
6133855239e5SApple OSS Distributions
6134855239e5SApple OSS Distributions array = OSDynamicCast(OSArray, obj);
6135855239e5SApple OSS Distributions if (array) {
6136855239e5SApple OSS Distributions if (!gIOCatalogue->resetAndAddDrivers(array,
6137855239e5SApple OSS Distributions flag == kIOCatalogResetDrivers)) {
6138855239e5SApple OSS Distributions kr = kIOReturnError;
6139855239e5SApple OSS Distributions }
6140855239e5SApple OSS Distributions } else {
6141855239e5SApple OSS Distributions kr = kIOReturnBadArgument;
6142855239e5SApple OSS Distributions }
6143855239e5SApple OSS Distributions }
6144855239e5SApple OSS Distributions break;
6145855239e5SApple OSS Distributions
6146c1dac77fSApple OSS Distributions case kIOCatalogAddDrivers:
6147c1dac77fSApple OSS Distributions case kIOCatalogAddDriversNoMatch: {
6148c1dac77fSApple OSS Distributions OSArray * array;
6149c1dac77fSApple OSS Distributions
6150c1dac77fSApple OSS Distributions array = OSDynamicCast(OSArray, obj);
6151c1dac77fSApple OSS Distributions if (array) {
6152c1dac77fSApple OSS Distributions if (!gIOCatalogue->addDrivers( array,
6153c1dac77fSApple OSS Distributions flag == kIOCatalogAddDrivers)) {
6154c1dac77fSApple OSS Distributions kr = kIOReturnError;
6155c1dac77fSApple OSS Distributions }
6156a5e72196SApple OSS Distributions } else {
6157c1dac77fSApple OSS Distributions kr = kIOReturnBadArgument;
6158c1dac77fSApple OSS Distributions }
6159c1dac77fSApple OSS Distributions }
6160c1dac77fSApple OSS Distributions break;
6161c1dac77fSApple OSS Distributions
6162c1dac77fSApple OSS Distributions case kIOCatalogRemoveDrivers:
6163c1dac77fSApple OSS Distributions case kIOCatalogRemoveDriversNoMatch: {
6164c1dac77fSApple OSS Distributions OSDictionary * dict;
6165c1dac77fSApple OSS Distributions
6166c1dac77fSApple OSS Distributions dict = OSDynamicCast(OSDictionary, obj);
6167c1dac77fSApple OSS Distributions if (dict) {
6168c1dac77fSApple OSS Distributions if (!gIOCatalogue->removeDrivers( dict,
6169c1dac77fSApple OSS Distributions flag == kIOCatalogRemoveDrivers )) {
6170c1dac77fSApple OSS Distributions kr = kIOReturnError;
6171c1dac77fSApple OSS Distributions }
6172a5e72196SApple OSS Distributions } else {
6173c1dac77fSApple OSS Distributions kr = kIOReturnBadArgument;
6174c1dac77fSApple OSS Distributions }
6175c1dac77fSApple OSS Distributions }
6176c1dac77fSApple OSS Distributions break;
6177c1dac77fSApple OSS Distributions
6178a5e72196SApple OSS Distributions case kIOCatalogStartMatching__Removed:
6179a5e72196SApple OSS Distributions case kIOCatalogRemoveKernelLinker__Removed:
61803ca3bd55SApple OSS Distributions case kIOCatalogKextdActive:
6181bb611c8fSApple OSS Distributions case kIOCatalogKextdFinishedLaunching:
6182bb611c8fSApple OSS Distributions kr = KERN_NOT_SUPPORTED;
6183e13b1fa5SApple OSS Distributions break;
6184e13b1fa5SApple OSS Distributions
6185c1dac77fSApple OSS Distributions default:
6186c1dac77fSApple OSS Distributions kr = kIOReturnBadArgument;
6187c1dac77fSApple OSS Distributions break;
6188c1dac77fSApple OSS Distributions }
6189c1dac77fSApple OSS Distributions
6190a5e72196SApple OSS Distributions if (obj) {
6191a5e72196SApple OSS Distributions obj->release();
6192a5e72196SApple OSS Distributions }
6193c1dac77fSApple OSS Distributions
6194c1dac77fSApple OSS Distributions *result = kr;
6195a5e72196SApple OSS Distributions return KERN_SUCCESS;
6196e6231be0SApple OSS Distributions #endif /* NO_KEXTD && !(DEVELOPMENT || DEBUG) */
6197c1dac77fSApple OSS Distributions }
6198c1dac77fSApple OSS Distributions
6199c1dac77fSApple OSS Distributions /* Routine io_catalog_terminate */
6200a5e72196SApple OSS Distributions kern_return_t
is_io_catalog_terminate(mach_port_t main_port,uint32_t flag,io_name_t name)6201a5e72196SApple OSS Distributions is_io_catalog_terminate(
62025c2921b0SApple OSS Distributions mach_port_t main_port,
6203e13b1fa5SApple OSS Distributions uint32_t flag,
6204c1dac77fSApple OSS Distributions io_name_t name )
6205c1dac77fSApple OSS Distributions {
6206c1dac77fSApple OSS Distributions kern_return_t kr;
6207c1dac77fSApple OSS Distributions
62085c2921b0SApple OSS Distributions if (main_port != main_device_port) {
6209c1dac77fSApple OSS Distributions return kIOReturnNotPrivileged;
6210a5e72196SApple OSS Distributions }
6211c1dac77fSApple OSS Distributions
6212c1dac77fSApple OSS Distributions kr = IOUserClient::clientHasPrivilege((void *) current_task(),
6213c1dac77fSApple OSS Distributions kIOClientPrivilegeAdministrator );
6214a5e72196SApple OSS Distributions if (kIOReturnSuccess != kr) {
6215a5e72196SApple OSS Distributions return kr;
6216a5e72196SApple OSS Distributions }
6217c1dac77fSApple OSS Distributions
6218c1dac77fSApple OSS Distributions switch (flag) {
6219855239e5SApple OSS Distributions #if !defined(SECURE_KERNEL)
6220c1dac77fSApple OSS Distributions case kIOCatalogServiceTerminate:
62215c2921b0SApple OSS Distributions kr = gIOCatalogue->terminateDrivers(NULL, name, false);
6222c1dac77fSApple OSS Distributions break;
6223c1dac77fSApple OSS Distributions
6224c1dac77fSApple OSS Distributions case kIOCatalogModuleUnload:
6225c1dac77fSApple OSS Distributions case kIOCatalogModuleTerminate:
6226c1dac77fSApple OSS Distributions kr = gIOCatalogue->terminateDriversForModule(name,
6227c1dac77fSApple OSS Distributions flag == kIOCatalogModuleUnload);
6228c1dac77fSApple OSS Distributions break;
6229855239e5SApple OSS Distributions #endif
6230c1dac77fSApple OSS Distributions
6231c1dac77fSApple OSS Distributions default:
6232c1dac77fSApple OSS Distributions kr = kIOReturnBadArgument;
6233c1dac77fSApple OSS Distributions break;
6234c1dac77fSApple OSS Distributions }
6235c1dac77fSApple OSS Distributions
6236a5e72196SApple OSS Distributions return kr;
6237c1dac77fSApple OSS Distributions }
6238c1dac77fSApple OSS Distributions
6239c1dac77fSApple OSS Distributions /* Routine io_catalog_get_data */
6240a5e72196SApple OSS Distributions kern_return_t
is_io_catalog_get_data(mach_port_t main_port,uint32_t flag,io_buf_ptr_t * outData,mach_msg_type_number_t * outDataCount)6241a5e72196SApple OSS Distributions is_io_catalog_get_data(
62425c2921b0SApple OSS Distributions mach_port_t main_port,
6243e13b1fa5SApple OSS Distributions uint32_t flag,
6244c1dac77fSApple OSS Distributions io_buf_ptr_t *outData,
6245c1dac77fSApple OSS Distributions mach_msg_type_number_t *outDataCount)
6246c1dac77fSApple OSS Distributions {
6247c1dac77fSApple OSS Distributions kern_return_t kr = kIOReturnSuccess;
6248c1dac77fSApple OSS Distributions OSSerialize * s;
6249c1dac77fSApple OSS Distributions
62505c2921b0SApple OSS Distributions if (main_port != main_device_port) {
6251c1dac77fSApple OSS Distributions return kIOReturnNotPrivileged;
6252a5e72196SApple OSS Distributions }
6253c1dac77fSApple OSS Distributions
6254c1dac77fSApple OSS Distributions //printf("io_catalog_get_data called. flag: %d\n", flag);
6255c1dac77fSApple OSS Distributions
6256c1dac77fSApple OSS Distributions s = OSSerialize::withCapacity(4096);
6257a5e72196SApple OSS Distributions if (!s) {
6258c1dac77fSApple OSS Distributions return kIOReturnNoMemory;
6259a5e72196SApple OSS Distributions }
6260c1dac77fSApple OSS Distributions
6261368ad365SApple OSS Distributions kr = gIOCatalogue->serializeData(flag, s);
6262c1dac77fSApple OSS Distributions
6263c1dac77fSApple OSS Distributions if (kr == kIOReturnSuccess) {
6264e7776783SApple OSS Distributions mach_vm_address_t data;
6265c1dac77fSApple OSS Distributions vm_map_copy_t copy;
6266bb611c8fSApple OSS Distributions unsigned int size;
6267c1dac77fSApple OSS Distributions
6268c1dac77fSApple OSS Distributions size = s->getLength();
6269*8d741a5dSApple OSS Distributions kr = mach_vm_allocate_kernel(kernel_map, &data, size,
6270*8d741a5dSApple OSS Distributions VM_MAP_KERNEL_FLAGS_ANYWHERE(.vm_tag = VM_KERN_MEMORY_IOKIT));
6271c1dac77fSApple OSS Distributions if (kr == kIOReturnSuccess) {
6272c1dac77fSApple OSS Distributions bcopy(s->text(), (void *)data, size);
6273e7776783SApple OSS Distributions kr = vm_map_copyin(kernel_map, data, size, true, ©);
6274c1dac77fSApple OSS Distributions *outData = (char *)copy;
6275c1dac77fSApple OSS Distributions *outDataCount = size;
6276c1dac77fSApple OSS Distributions }
6277c1dac77fSApple OSS Distributions }
6278c1dac77fSApple OSS Distributions
6279c1dac77fSApple OSS Distributions s->release();
6280c1dac77fSApple OSS Distributions
6281c1dac77fSApple OSS Distributions return kr;
6282c1dac77fSApple OSS Distributions }
6283c1dac77fSApple OSS Distributions
6284c1dac77fSApple OSS Distributions /* Routine io_catalog_get_gen_count */
6285a5e72196SApple OSS Distributions kern_return_t
is_io_catalog_get_gen_count(mach_port_t main_port,uint32_t * genCount)6286a5e72196SApple OSS Distributions is_io_catalog_get_gen_count(
62875c2921b0SApple OSS Distributions mach_port_t main_port,
6288e13b1fa5SApple OSS Distributions uint32_t *genCount)
6289c1dac77fSApple OSS Distributions {
62905c2921b0SApple OSS Distributions if (main_port != main_device_port) {
6291c1dac77fSApple OSS Distributions return kIOReturnNotPrivileged;
6292a5e72196SApple OSS Distributions }
6293c1dac77fSApple OSS Distributions
6294c1dac77fSApple OSS Distributions //printf("io_catalog_get_gen_count called.\n");
6295c1dac77fSApple OSS Distributions
6296a5e72196SApple OSS Distributions if (!genCount) {
6297c1dac77fSApple OSS Distributions return kIOReturnBadArgument;
6298a5e72196SApple OSS Distributions }
6299c1dac77fSApple OSS Distributions
6300c1dac77fSApple OSS Distributions *genCount = gIOCatalogue->getGenerationCount();
6301c1dac77fSApple OSS Distributions
6302c1dac77fSApple OSS Distributions return kIOReturnSuccess;
6303c1dac77fSApple OSS Distributions }
6304c1dac77fSApple OSS Distributions
63053ca3bd55SApple OSS Distributions /* Routine io_catalog_module_loaded.
63063ca3bd55SApple OSS Distributions * Is invoked from IOKitLib's IOCatalogueModuleLoaded(). Doesn't seem to be used.
63073ca3bd55SApple OSS Distributions */
6308a5e72196SApple OSS Distributions kern_return_t
is_io_catalog_module_loaded(mach_port_t main_port,io_name_t name)6309a5e72196SApple OSS Distributions is_io_catalog_module_loaded(
63105c2921b0SApple OSS Distributions mach_port_t main_port,
6311c1dac77fSApple OSS Distributions io_name_t name)
6312c1dac77fSApple OSS Distributions {
63135c2921b0SApple OSS Distributions if (main_port != main_device_port) {
6314c1dac77fSApple OSS Distributions return kIOReturnNotPrivileged;
6315a5e72196SApple OSS Distributions }
6316c1dac77fSApple OSS Distributions
6317c1dac77fSApple OSS Distributions //printf("io_catalog_module_loaded called. name %s\n", name);
6318c1dac77fSApple OSS Distributions
6319a5e72196SApple OSS Distributions if (!name) {
6320c1dac77fSApple OSS Distributions return kIOReturnBadArgument;
6321a5e72196SApple OSS Distributions }
6322c1dac77fSApple OSS Distributions
6323c1dac77fSApple OSS Distributions gIOCatalogue->moduleHasLoaded(name);
6324c1dac77fSApple OSS Distributions
6325c1dac77fSApple OSS Distributions return kIOReturnSuccess;
6326c1dac77fSApple OSS Distributions }
6327c1dac77fSApple OSS Distributions
6328a5e72196SApple OSS Distributions kern_return_t
is_io_catalog_reset(mach_port_t main_port,uint32_t flag)6329a5e72196SApple OSS Distributions is_io_catalog_reset(
63305c2921b0SApple OSS Distributions mach_port_t main_port,
6331e13b1fa5SApple OSS Distributions uint32_t flag)
6332c1dac77fSApple OSS Distributions {
63335c2921b0SApple OSS Distributions if (main_port != main_device_port) {
6334c1dac77fSApple OSS Distributions return kIOReturnNotPrivileged;
6335a5e72196SApple OSS Distributions }
6336c1dac77fSApple OSS Distributions
6337c1dac77fSApple OSS Distributions switch (flag) {
6338c1dac77fSApple OSS Distributions case kIOCatalogResetDefault:
6339c1dac77fSApple OSS Distributions gIOCatalogue->reset();
6340c1dac77fSApple OSS Distributions break;
6341c1dac77fSApple OSS Distributions
6342c1dac77fSApple OSS Distributions default:
6343c1dac77fSApple OSS Distributions return kIOReturnBadArgument;
6344c1dac77fSApple OSS Distributions }
6345c1dac77fSApple OSS Distributions
6346c1dac77fSApple OSS Distributions return kIOReturnSuccess;
6347c1dac77fSApple OSS Distributions }
6348c1dac77fSApple OSS Distributions
6349a5e72196SApple OSS Distributions kern_return_t
iokit_user_client_trap(struct iokit_user_client_trap_args * args)6350a5e72196SApple OSS Distributions iokit_user_client_trap(struct iokit_user_client_trap_args *args)
6351c1dac77fSApple OSS Distributions {
6352c1dac77fSApple OSS Distributions kern_return_t result = kIOReturnBadArgument;
6353c1dac77fSApple OSS Distributions IOUserClient * userClient;
6354a5e72196SApple OSS Distributions OSObject * object;
6355a5e72196SApple OSS Distributions uintptr_t ref;
6356e6231be0SApple OSS Distributions mach_port_name_t portName;
6357c1dac77fSApple OSS Distributions
6358a5e72196SApple OSS Distributions ref = (uintptr_t) args->userClientRef;
6359e6231be0SApple OSS Distributions
6360e6231be0SApple OSS Distributions if ((ref == MACH_PORT_DEAD) || (ref == (uintptr_t) MACH_PORT_NULL)) {
6361e6231be0SApple OSS Distributions return kIOReturnBadArgument;
6362e6231be0SApple OSS Distributions }
6363e6231be0SApple OSS Distributions // kobject port names always have b0-1 set, so we use these bits as flags to
6364e6231be0SApple OSS Distributions // iokit_user_client_trap()
6365e6231be0SApple OSS Distributions // keep this up to date with ipc_entry_name_mask();
6366e6231be0SApple OSS Distributions portName = (mach_port_name_t) (ref | 3);
6367e6231be0SApple OSS Distributions if (((1ULL << 32) & ref) || !(1 & ref)) {
6368e6231be0SApple OSS Distributions object = iokit_lookup_uext_ref_current_task(portName);
6369a5e72196SApple OSS Distributions if (object) {
6370a5e72196SApple OSS Distributions result = IOUserServerUEXTTrap(object, args->p1, args->p2, args->p3, args->p4, args->p5, args->p6);
6371a5e72196SApple OSS Distributions }
6372a5e72196SApple OSS Distributions OSSafeReleaseNULL(object);
6373e6231be0SApple OSS Distributions } else {
6374e6231be0SApple OSS Distributions io_object_t ref_current_task = iokit_lookup_connect_ref_current_task((mach_port_name_t) ref);
6375e6231be0SApple OSS Distributions if ((userClient = OSDynamicCast(IOUserClient, ref_current_task))) {
6376bb611c8fSApple OSS Distributions IOExternalTrap *trap = NULL;
6377c1dac77fSApple OSS Distributions IOService *target = NULL;
6378c1dac77fSApple OSS Distributions
6379bb611c8fSApple OSS Distributions result = kIOReturnSuccess;
6380bb611c8fSApple OSS Distributions io_filter_policy_t filterPolicy = userClient->filterForTask(current_task(), 0);
6381bb611c8fSApple OSS Distributions if (filterPolicy && gIOUCFilterCallbacks->io_filter_applier) {
6382e6231be0SApple OSS Distributions result = gIOUCFilterCallbacks->io_filter_applier(userClient, filterPolicy, io_filter_type_trap, args->index);
6383bb611c8fSApple OSS Distributions }
6384bb611c8fSApple OSS Distributions if (kIOReturnSuccess == result) {
638514e3d835SApple OSS Distributions trap = userClient->getTargetAndTrapForIndex(&target, args->index);
6386bb611c8fSApple OSS Distributions }
6387c1dac77fSApple OSS Distributions if (trap && target) {
6388c1dac77fSApple OSS Distributions IOTrap func;
6389c1dac77fSApple OSS Distributions
6390c1dac77fSApple OSS Distributions func = trap->func;
6391c1dac77fSApple OSS Distributions
6392c1dac77fSApple OSS Distributions if (func) {
639314e3d835SApple OSS Distributions result = (target->*func)(args->p1, args->p2, args->p3, args->p4, args->p5, args->p6);
6394c1dac77fSApple OSS Distributions }
6395c1dac77fSApple OSS Distributions }
6396c1dac77fSApple OSS Distributions
639788cc0b97SApple OSS Distributions iokit_remove_connect_reference(userClient);
6398e6231be0SApple OSS Distributions } else {
6399e6231be0SApple OSS Distributions OSSafeReleaseNULL(ref_current_task);
6400e6231be0SApple OSS Distributions }
6401c1dac77fSApple OSS Distributions }
6402c1dac77fSApple OSS Distributions
6403c1dac77fSApple OSS Distributions return result;
6404c1dac77fSApple OSS Distributions }
6405c1dac77fSApple OSS Distributions
6406cc9a6355SApple OSS Distributions /* Routine io_device_tree_entry_exists_with_name */
6407a5e72196SApple OSS Distributions kern_return_t
is_io_device_tree_entry_exists_with_name(mach_port_t main_port,io_name_t name,boolean_t * exists)6408a5e72196SApple OSS Distributions is_io_device_tree_entry_exists_with_name(
64095c2921b0SApple OSS Distributions mach_port_t main_port,
6410cc9a6355SApple OSS Distributions io_name_t name,
6411cc9a6355SApple OSS Distributions boolean_t *exists )
6412cc9a6355SApple OSS Distributions {
6413cc9a6355SApple OSS Distributions OSCollectionIterator *iter;
6414cc9a6355SApple OSS Distributions
64155c2921b0SApple OSS Distributions if (main_port != main_device_port) {
6416a5e72196SApple OSS Distributions return kIOReturnNotPrivileged;
6417a5e72196SApple OSS Distributions }
6418cc9a6355SApple OSS Distributions
6419cc9a6355SApple OSS Distributions iter = IODTFindMatchingEntries(IORegistryEntry::getRegistryRoot(), kIODTRecursive, name);
6420cc9a6355SApple OSS Distributions *exists = iter && iter->getNextObject();
6421cc9a6355SApple OSS Distributions OSSafeReleaseNULL(iter);
6422cc9a6355SApple OSS Distributions
6423cc9a6355SApple OSS Distributions return kIOReturnSuccess;
6424cc9a6355SApple OSS Distributions }
6425855239e5SApple OSS Distributions } /* extern "C" */
6426855239e5SApple OSS Distributions
6427a5e72196SApple OSS Distributions IOReturn
callExternalMethod(uint32_t selector,IOExternalMethodArguments * args)64285c2921b0SApple OSS Distributions IOUserClient::callExternalMethod(uint32_t selector, IOExternalMethodArguments * args)
64295c2921b0SApple OSS Distributions {
64305c2921b0SApple OSS Distributions IOReturn ret;
64315c2921b0SApple OSS Distributions
643294d3b452SApple OSS Distributions ipcEnter(defaultLocking ? (defaultLockingSingleThreadExternalMethod ? kIPCLockWrite : kIPCLockRead) : kIPCLockNone);
64335c2921b0SApple OSS Distributions if (uc2022) {
64345c2921b0SApple OSS Distributions ret = ((IOUserClient2022 *) this)->externalMethod(selector, (IOExternalMethodArgumentsOpaque *) args);
64355c2921b0SApple OSS Distributions } else {
64365c2921b0SApple OSS Distributions ret = externalMethod(selector, args);
64375c2921b0SApple OSS Distributions }
643894d3b452SApple OSS Distributions ipcExit(defaultLocking ? (defaultLockingSingleThreadExternalMethod ? kIPCLockWrite : kIPCLockRead) : kIPCLockNone);
643994d3b452SApple OSS Distributions
64405c2921b0SApple OSS Distributions return ret;
64415c2921b0SApple OSS Distributions }
64425c2921b0SApple OSS Distributions
64435c2921b0SApple OSS Distributions MIG_SERVER_ROUTINE IOReturn
externalMethod(uint32_t selector,IOExternalMethodArguments * arguments,IOExternalMethodDispatch * dispatch,OSObject * target,void * reference)64445c2921b0SApple OSS Distributions IOUserClient2022::externalMethod(uint32_t selector, IOExternalMethodArguments * arguments,
64455c2921b0SApple OSS Distributions IOExternalMethodDispatch *dispatch,
64465c2921b0SApple OSS Distributions OSObject *target, void *reference)
64475c2921b0SApple OSS Distributions {
64485c2921b0SApple OSS Distributions panic("wrong externalMethod for IOUserClient2022");
64495c2921b0SApple OSS Distributions }
64505c2921b0SApple OSS Distributions
64515c2921b0SApple OSS Distributions IOReturn
dispatchExternalMethod(uint32_t selector,IOExternalMethodArgumentsOpaque * arguments,const IOExternalMethodDispatch2022 dispatchArray[],size_t dispatchArrayCount,OSObject * target,void * reference)64525c2921b0SApple OSS Distributions IOUserClient2022::dispatchExternalMethod(uint32_t selector, IOExternalMethodArgumentsOpaque *arguments,
64535c2921b0SApple OSS Distributions const IOExternalMethodDispatch2022 dispatchArray[], size_t dispatchArrayCount,
64545c2921b0SApple OSS Distributions OSObject * target, void * reference)
64555c2921b0SApple OSS Distributions {
64565c2921b0SApple OSS Distributions IOReturn err;
64575c2921b0SApple OSS Distributions IOExternalMethodArguments * args = (typeof(args))arguments;
64585c2921b0SApple OSS Distributions const IOExternalMethodDispatch2022 * dispatch;
64595c2921b0SApple OSS Distributions
64605c2921b0SApple OSS Distributions if (!dispatchArray) {
64615c2921b0SApple OSS Distributions return kIOReturnError;
64625c2921b0SApple OSS Distributions }
64635c2921b0SApple OSS Distributions if (selector >= dispatchArrayCount) {
64645c2921b0SApple OSS Distributions return kIOReturnBadArgument;
64655c2921b0SApple OSS Distributions }
64665c2921b0SApple OSS Distributions dispatch = &dispatchArray[selector];
64675c2921b0SApple OSS Distributions
64685c2921b0SApple OSS Distributions uint32_t count;
64695c2921b0SApple OSS Distributions count = dispatch->checkScalarInputCount;
64705c2921b0SApple OSS Distributions if ((kIOUCVariableStructureSize != count) && (count != args->scalarInputCount)) {
64715c2921b0SApple OSS Distributions return kIOReturnBadArgument;
64725c2921b0SApple OSS Distributions }
64735c2921b0SApple OSS Distributions
64745c2921b0SApple OSS Distributions count = dispatch->checkStructureInputSize;
64755c2921b0SApple OSS Distributions if ((kIOUCVariableStructureSize != count)
64765c2921b0SApple OSS Distributions && (count != ((args->structureInputDescriptor)
64775c2921b0SApple OSS Distributions ? args->structureInputDescriptor->getLength() : args->structureInputSize))) {
64785c2921b0SApple OSS Distributions return kIOReturnBadArgument;
64795c2921b0SApple OSS Distributions }
64805c2921b0SApple OSS Distributions
64815c2921b0SApple OSS Distributions count = dispatch->checkScalarOutputCount;
64825c2921b0SApple OSS Distributions if ((kIOUCVariableStructureSize != count) && (count != args->scalarOutputCount)) {
64835c2921b0SApple OSS Distributions return kIOReturnBadArgument;
64845c2921b0SApple OSS Distributions }
64855c2921b0SApple OSS Distributions
64865c2921b0SApple OSS Distributions count = dispatch->checkStructureOutputSize;
64875c2921b0SApple OSS Distributions if ((kIOUCVariableStructureSize != count)
64885c2921b0SApple OSS Distributions && (count != ((args->structureOutputDescriptor)
64895c2921b0SApple OSS Distributions ? args->structureOutputDescriptor->getLength() : args->structureOutputSize))) {
64905c2921b0SApple OSS Distributions return kIOReturnBadArgument;
64915c2921b0SApple OSS Distributions }
64925c2921b0SApple OSS Distributions
64935c2921b0SApple OSS Distributions if (args->asyncWakePort && !dispatch->allowAsync) {
64945c2921b0SApple OSS Distributions return kIOReturnBadArgument;
64955c2921b0SApple OSS Distributions }
64965c2921b0SApple OSS Distributions
64975c2921b0SApple OSS Distributions if (dispatch->checkEntitlement) {
64985c2921b0SApple OSS Distributions if (!IOCurrentTaskHasEntitlement(dispatch->checkEntitlement)) {
64995c2921b0SApple OSS Distributions return kIOReturnNotPrivileged;
65005c2921b0SApple OSS Distributions }
65015c2921b0SApple OSS Distributions }
65025c2921b0SApple OSS Distributions
65035c2921b0SApple OSS Distributions if (dispatch->function) {
65045c2921b0SApple OSS Distributions err = (*dispatch->function)(target, reference, args);
65055c2921b0SApple OSS Distributions } else {
65065c2921b0SApple OSS Distributions err = kIOReturnNoCompletion; /* implementer can dispatch */
65075c2921b0SApple OSS Distributions }
65085c2921b0SApple OSS Distributions return err;
65095c2921b0SApple OSS Distributions }
65105c2921b0SApple OSS Distributions
65115c2921b0SApple OSS Distributions IOReturn
externalMethod(uint32_t selector,IOExternalMethodArguments * args,IOExternalMethodDispatch * dispatch,OSObject * target,void * reference)6512a5e72196SApple OSS Distributions IOUserClient::externalMethod( uint32_t selector, IOExternalMethodArguments * args,
6513e13b1fa5SApple OSS Distributions IOExternalMethodDispatch * dispatch, OSObject * target, void * reference )
6514e13b1fa5SApple OSS Distributions {
6515e13b1fa5SApple OSS Distributions IOReturn err;
6516e13b1fa5SApple OSS Distributions IOService * object;
65173ca3bd55SApple OSS Distributions IOByteCount structureOutputSize;
6518e13b1fa5SApple OSS Distributions
6519a5e72196SApple OSS Distributions if (dispatch) {
6520e13b1fa5SApple OSS Distributions uint32_t count;
6521e13b1fa5SApple OSS Distributions count = dispatch->checkScalarInputCount;
6522a5e72196SApple OSS Distributions if ((kIOUCVariableStructureSize != count) && (count != args->scalarInputCount)) {
6523a5e72196SApple OSS Distributions return kIOReturnBadArgument;
6524e13b1fa5SApple OSS Distributions }
6525e13b1fa5SApple OSS Distributions
6526e13b1fa5SApple OSS Distributions count = dispatch->checkStructureInputSize;
6527e13b1fa5SApple OSS Distributions if ((kIOUCVariableStructureSize != count)
6528e13b1fa5SApple OSS Distributions && (count != ((args->structureInputDescriptor)
6529a5e72196SApple OSS Distributions ? args->structureInputDescriptor->getLength() : args->structureInputSize))) {
6530a5e72196SApple OSS Distributions return kIOReturnBadArgument;
6531e13b1fa5SApple OSS Distributions }
6532e13b1fa5SApple OSS Distributions
6533e13b1fa5SApple OSS Distributions count = dispatch->checkScalarOutputCount;
6534a5e72196SApple OSS Distributions if ((kIOUCVariableStructureSize != count) && (count != args->scalarOutputCount)) {
6535a5e72196SApple OSS Distributions return kIOReturnBadArgument;
6536e13b1fa5SApple OSS Distributions }
6537e13b1fa5SApple OSS Distributions
6538e13b1fa5SApple OSS Distributions count = dispatch->checkStructureOutputSize;
6539e13b1fa5SApple OSS Distributions if ((kIOUCVariableStructureSize != count)
6540e13b1fa5SApple OSS Distributions && (count != ((args->structureOutputDescriptor)
6541a5e72196SApple OSS Distributions ? args->structureOutputDescriptor->getLength() : args->structureOutputSize))) {
6542a5e72196SApple OSS Distributions return kIOReturnBadArgument;
6543e13b1fa5SApple OSS Distributions }
6544e13b1fa5SApple OSS Distributions
6545a5e72196SApple OSS Distributions if (dispatch->function) {
6546e13b1fa5SApple OSS Distributions err = (*dispatch->function)(target, reference, args);
6547a5e72196SApple OSS Distributions } else {
65485c2921b0SApple OSS Distributions err = kIOReturnNoCompletion; /* implementer can dispatch */
6549a5e72196SApple OSS Distributions }
6550a5e72196SApple OSS Distributions return err;
6551e13b1fa5SApple OSS Distributions }
6552e13b1fa5SApple OSS Distributions
65533ca3bd55SApple OSS Distributions
6554e13b1fa5SApple OSS Distributions // pre-Leopard API's don't do ool structs
6555a5e72196SApple OSS Distributions if (args->structureInputDescriptor || args->structureOutputDescriptor) {
6556e13b1fa5SApple OSS Distributions err = kIOReturnIPCError;
6557a5e72196SApple OSS Distributions return err;
6558e13b1fa5SApple OSS Distributions }
6559e13b1fa5SApple OSS Distributions
65603ca3bd55SApple OSS Distributions structureOutputSize = args->structureOutputSize;
65613ca3bd55SApple OSS Distributions
6562a5e72196SApple OSS Distributions if (args->asyncWakePort) {
6563e13b1fa5SApple OSS Distributions IOExternalAsyncMethod * method;
6564a5e72196SApple OSS Distributions object = NULL;
6565a5e72196SApple OSS Distributions if (!(method = getAsyncTargetAndMethodForIndex(&object, selector)) || !object) {
6566a5e72196SApple OSS Distributions return kIOReturnUnsupported;
6567855239e5SApple OSS Distributions }
6568855239e5SApple OSS Distributions
6569a5e72196SApple OSS Distributions if (kIOUCForegroundOnly & method->flags) {
6570a5e72196SApple OSS Distributions if (task_is_gpu_denied(current_task())) {
6571a5e72196SApple OSS Distributions return kIOReturnNotPermitted;
6572a5e72196SApple OSS Distributions }
6573a5e72196SApple OSS Distributions }
6574a5e72196SApple OSS Distributions
6575a5e72196SApple OSS Distributions switch (method->flags & kIOUCTypeMask) {
6576e13b1fa5SApple OSS Distributions case kIOUCScalarIStructI:
6577e13b1fa5SApple OSS Distributions err = shim_io_async_method_scalarI_structureI( method, object,
6578e13b1fa5SApple OSS Distributions args->asyncWakePort, args->asyncReference, args->asyncReferenceCount,
6579e13b1fa5SApple OSS Distributions args->scalarInput, args->scalarInputCount,
6580e13b1fa5SApple OSS Distributions (char *)args->structureInput, args->structureInputSize );
6581e13b1fa5SApple OSS Distributions break;
6582e13b1fa5SApple OSS Distributions
6583e13b1fa5SApple OSS Distributions case kIOUCScalarIScalarO:
6584e13b1fa5SApple OSS Distributions err = shim_io_async_method_scalarI_scalarO( method, object,
6585e13b1fa5SApple OSS Distributions args->asyncWakePort, args->asyncReference, args->asyncReferenceCount,
6586e13b1fa5SApple OSS Distributions args->scalarInput, args->scalarInputCount,
6587e13b1fa5SApple OSS Distributions args->scalarOutput, &args->scalarOutputCount );
6588e13b1fa5SApple OSS Distributions break;
6589e13b1fa5SApple OSS Distributions
6590e13b1fa5SApple OSS Distributions case kIOUCScalarIStructO:
6591e13b1fa5SApple OSS Distributions err = shim_io_async_method_scalarI_structureO( method, object,
6592e13b1fa5SApple OSS Distributions args->asyncWakePort, args->asyncReference, args->asyncReferenceCount,
6593e13b1fa5SApple OSS Distributions args->scalarInput, args->scalarInputCount,
6594e13b1fa5SApple OSS Distributions (char *) args->structureOutput, &args->structureOutputSize );
6595e13b1fa5SApple OSS Distributions break;
6596e13b1fa5SApple OSS Distributions
6597e13b1fa5SApple OSS Distributions
6598e13b1fa5SApple OSS Distributions case kIOUCStructIStructO:
6599e13b1fa5SApple OSS Distributions err = shim_io_async_method_structureI_structureO( method, object,
6600e13b1fa5SApple OSS Distributions args->asyncWakePort, args->asyncReference, args->asyncReferenceCount,
6601e13b1fa5SApple OSS Distributions (char *)args->structureInput, args->structureInputSize,
6602e13b1fa5SApple OSS Distributions (char *) args->structureOutput, &args->structureOutputSize );
6603e13b1fa5SApple OSS Distributions break;
6604e13b1fa5SApple OSS Distributions
6605e13b1fa5SApple OSS Distributions default:
6606e13b1fa5SApple OSS Distributions err = kIOReturnBadArgument;
6607e13b1fa5SApple OSS Distributions break;
6608e13b1fa5SApple OSS Distributions }
6609a5e72196SApple OSS Distributions } else {
6610e13b1fa5SApple OSS Distributions IOExternalMethod * method;
6611a5e72196SApple OSS Distributions object = NULL;
6612a5e72196SApple OSS Distributions if (!(method = getTargetAndMethodForIndex(&object, selector)) || !object) {
6613a5e72196SApple OSS Distributions return kIOReturnUnsupported;
6614855239e5SApple OSS Distributions }
6615855239e5SApple OSS Distributions
6616a5e72196SApple OSS Distributions if (kIOUCForegroundOnly & method->flags) {
6617a5e72196SApple OSS Distributions if (task_is_gpu_denied(current_task())) {
6618a5e72196SApple OSS Distributions return kIOReturnNotPermitted;
6619a5e72196SApple OSS Distributions }
6620a5e72196SApple OSS Distributions }
6621a5e72196SApple OSS Distributions
6622a5e72196SApple OSS Distributions switch (method->flags & kIOUCTypeMask) {
6623e13b1fa5SApple OSS Distributions case kIOUCScalarIStructI:
6624e13b1fa5SApple OSS Distributions err = shim_io_connect_method_scalarI_structureI( method, object,
6625e13b1fa5SApple OSS Distributions args->scalarInput, args->scalarInputCount,
6626e13b1fa5SApple OSS Distributions (char *) args->structureInput, args->structureInputSize );
6627e13b1fa5SApple OSS Distributions break;
6628e13b1fa5SApple OSS Distributions
6629e13b1fa5SApple OSS Distributions case kIOUCScalarIScalarO:
6630e13b1fa5SApple OSS Distributions err = shim_io_connect_method_scalarI_scalarO( method, object,
6631e13b1fa5SApple OSS Distributions args->scalarInput, args->scalarInputCount,
6632e13b1fa5SApple OSS Distributions args->scalarOutput, &args->scalarOutputCount );
6633e13b1fa5SApple OSS Distributions break;
6634e13b1fa5SApple OSS Distributions
6635e13b1fa5SApple OSS Distributions case kIOUCScalarIStructO:
6636e13b1fa5SApple OSS Distributions err = shim_io_connect_method_scalarI_structureO( method, object,
6637e13b1fa5SApple OSS Distributions args->scalarInput, args->scalarInputCount,
66383ca3bd55SApple OSS Distributions (char *) args->structureOutput, &structureOutputSize );
6639e13b1fa5SApple OSS Distributions break;
6640e13b1fa5SApple OSS Distributions
6641e13b1fa5SApple OSS Distributions
6642e13b1fa5SApple OSS Distributions case kIOUCStructIStructO:
6643e13b1fa5SApple OSS Distributions err = shim_io_connect_method_structureI_structureO( method, object,
6644e13b1fa5SApple OSS Distributions (char *) args->structureInput, args->structureInputSize,
66453ca3bd55SApple OSS Distributions (char *) args->structureOutput, &structureOutputSize );
6646e13b1fa5SApple OSS Distributions break;
6647e13b1fa5SApple OSS Distributions
6648e13b1fa5SApple OSS Distributions default:
6649e13b1fa5SApple OSS Distributions err = kIOReturnBadArgument;
6650e13b1fa5SApple OSS Distributions break;
6651e13b1fa5SApple OSS Distributions }
6652e13b1fa5SApple OSS Distributions }
66533ca3bd55SApple OSS Distributions
6654bb611c8fSApple OSS Distributions if (structureOutputSize > UINT_MAX) {
6655bb611c8fSApple OSS Distributions structureOutputSize = 0;
6656bb611c8fSApple OSS Distributions err = kIOReturnBadArgument;
6657bb611c8fSApple OSS Distributions }
6658bb611c8fSApple OSS Distributions
6659bb611c8fSApple OSS Distributions args->structureOutputSize = ((typeof(args->structureOutputSize))structureOutputSize);
66603ca3bd55SApple OSS Distributions
6661a5e72196SApple OSS Distributions return err;
6662e13b1fa5SApple OSS Distributions }
6663e13b1fa5SApple OSS Distributions
6664bb611c8fSApple OSS Distributions IOReturn
registerFilterCallbacks(const struct io_filter_callbacks * callbacks,size_t size)6665bb611c8fSApple OSS Distributions IOUserClient::registerFilterCallbacks(const struct io_filter_callbacks *callbacks, size_t size)
6666bb611c8fSApple OSS Distributions {
6667bb611c8fSApple OSS Distributions if (size < sizeof(*callbacks)) {
6668bb611c8fSApple OSS Distributions return kIOReturnBadArgument;
6669bb611c8fSApple OSS Distributions }
6670bb611c8fSApple OSS Distributions if (!OSCompareAndSwapPtr(NULL, __DECONST(void *, callbacks), &gIOUCFilterCallbacks)) {
6671bb611c8fSApple OSS Distributions return kIOReturnBusy;
6672bb611c8fSApple OSS Distributions }
6673bb611c8fSApple OSS Distributions return kIOReturnSuccess;
6674bb611c8fSApple OSS Distributions }
6675bb611c8fSApple OSS Distributions
66765c2921b0SApple OSS Distributions
66773ca3bd55SApple OSS Distributions OSMetaClassDefineReservedUnused(IOUserClient, 0);
6678c1dac77fSApple OSS Distributions OSMetaClassDefineReservedUnused(IOUserClient, 1);
6679c1dac77fSApple OSS Distributions OSMetaClassDefineReservedUnused(IOUserClient, 2);
6680c1dac77fSApple OSS Distributions OSMetaClassDefineReservedUnused(IOUserClient, 3);
6681c1dac77fSApple OSS Distributions OSMetaClassDefineReservedUnused(IOUserClient, 4);
6682c1dac77fSApple OSS Distributions OSMetaClassDefineReservedUnused(IOUserClient, 5);
6683c1dac77fSApple OSS Distributions OSMetaClassDefineReservedUnused(IOUserClient, 6);
6684c1dac77fSApple OSS Distributions OSMetaClassDefineReservedUnused(IOUserClient, 7);
6685c1dac77fSApple OSS Distributions OSMetaClassDefineReservedUnused(IOUserClient, 8);
6686c1dac77fSApple OSS Distributions OSMetaClassDefineReservedUnused(IOUserClient, 9);
6687c1dac77fSApple OSS Distributions OSMetaClassDefineReservedUnused(IOUserClient, 10);
6688c1dac77fSApple OSS Distributions OSMetaClassDefineReservedUnused(IOUserClient, 11);
6689c1dac77fSApple OSS Distributions OSMetaClassDefineReservedUnused(IOUserClient, 12);
6690c1dac77fSApple OSS Distributions OSMetaClassDefineReservedUnused(IOUserClient, 13);
6691c1dac77fSApple OSS Distributions OSMetaClassDefineReservedUnused(IOUserClient, 14);
6692c1dac77fSApple OSS Distributions OSMetaClassDefineReservedUnused(IOUserClient, 15);
66935c2921b0SApple OSS Distributions
66945c2921b0SApple OSS Distributions OSMetaClassDefineReservedUnused(IOUserClient2022, 0);
66955c2921b0SApple OSS Distributions OSMetaClassDefineReservedUnused(IOUserClient2022, 1);
66965c2921b0SApple OSS Distributions OSMetaClassDefineReservedUnused(IOUserClient2022, 2);
66975c2921b0SApple OSS Distributions OSMetaClassDefineReservedUnused(IOUserClient2022, 3);
6698