2 * Copyright (c) 1998-2011 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
30 #include <libkern/c++/OSKext.h>
31 #include <IOKit/IOKitServer.h>
32 #include <IOKit/IOKitKeysPrivate.h>
33 #include <IOKit/IOUserClient.h>
34 #include <IOKit/IOService.h>
35 #include <IOKit/IORegistryEntry.h>
36 #include <IOKit/IOCatalogue.h>
37 #include <IOKit/IOMemoryDescriptor.h>
38 #include <IOKit/IOBufferMemoryDescriptor.h>
39 #include <IOKit/IOLib.h>
40 #include <IOKit/IOStatisticsPrivate.h>
41 #include <IOKit/IOTimeStamp.h>
42 #include <libkern/OSDebug.h>
44 #include <sys/kauth.h>
49 #include <security/mac_framework.h>
51 #include <sys/kauth.h>
55 #endif /* CONFIG_MACF */
57 #include <IOKit/assert.h>
59 #include "IOServicePrivate.h"
60 #include "IOKitKernelInternal.h"
62 #define SCALAR64(x) ((io_user_scalar_t)((unsigned int)x))
63 #define SCALAR32(x) ((uint32_t )x)
64 #define ARG32(x) ((void *)SCALAR32(x))
65 #define REF64(x) ((io_user_reference_t)((UInt64)(x)))
66 #define REF32(x) ((int)(x))
70 kIOUCAsync0Flags
= 3ULL,
71 kIOUCAsync64Flag
= 1ULL
76 #define IOStatisticsRegisterCounter() \
78 reserved->counter = IOStatistics::registerUserClient(this); \
81 #define IOStatisticsUnregisterCounter() \
84 IOStatistics::unregisterUserClient(reserved->counter); \
87 #define IOStatisticsClientCall() \
89 IOStatistics::countUserClientCall(client); \
94 #define IOStatisticsRegisterCounter()
95 #define IOStatisticsUnregisterCounter()
96 #define IOStatisticsClientCall()
98 #endif /* IOKITSTATS */
100 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
102 // definitions we should get from osfmk
104 //typedef struct ipc_port * ipc_port_t;
105 typedef natural_t ipc_kobject_type_t
;
107 #define IKOT_IOKIT_SPARE 27
108 #define IKOT_IOKIT_CONNECT 29
109 #define IKOT_IOKIT_OBJECT 30
113 extern ipc_port_t
iokit_alloc_object_port( io_object_t obj
,
114 ipc_kobject_type_t type
);
116 extern kern_return_t
iokit_destroy_object_port( ipc_port_t port
);
118 extern mach_port_name_t
iokit_make_send_right( task_t task
,
119 io_object_t obj
, ipc_kobject_type_t type
);
121 extern kern_return_t
iokit_mod_send_right( task_t task
, mach_port_name_t name
, mach_port_delta_t delta
);
123 extern io_object_t
iokit_lookup_connect_ref(io_object_t clientRef
, ipc_space_t task
);
125 extern io_object_t
iokit_lookup_connect_ref_current_task(io_object_t clientRef
);
127 extern ipc_port_t master_device_port
;
129 extern void iokit_retain_port( ipc_port_t port
);
130 extern void iokit_release_port( ipc_port_t port
);
131 extern void iokit_release_port_send( ipc_port_t port
);
133 extern kern_return_t
iokit_switch_object_port( ipc_port_t port
, io_object_t obj
, ipc_kobject_type_t type
);
135 #include <mach/mach_traps.h>
136 #include <vm/vm_map.h>
141 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
143 // IOMachPort maps OSObjects to ports, avoiding adding an ivar to OSObject.
145 class IOMachPort
: public OSObject
147 OSDeclareDefaultStructors(IOMachPort
)
154 static IOMachPort
* portForObject( OSObject
* obj
,
155 ipc_kobject_type_t type
);
156 static bool noMoreSendersForObject( OSObject
* obj
,
157 ipc_kobject_type_t type
, mach_port_mscount_t
* mscount
);
158 static void releasePortForObject( OSObject
* obj
,
159 ipc_kobject_type_t type
);
160 static void setHoldDestroy( OSObject
* obj
, ipc_kobject_type_t type
);
162 static OSDictionary
* dictForType( ipc_kobject_type_t type
);
164 static mach_port_name_t
makeSendRightForTask( task_t task
,
165 io_object_t obj
, ipc_kobject_type_t type
);
170 #define super OSObject
171 OSDefineMetaClassAndStructors(IOMachPort
, OSObject
)
173 static IOLock
* gIOObjectPortLock
;
175 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
177 // not in dictForType() for debugging ease
178 static OSDictionary
* gIOObjectPorts
;
179 static OSDictionary
* gIOConnectPorts
;
181 OSDictionary
* IOMachPort::dictForType( ipc_kobject_type_t type
)
183 OSDictionary
** dict
;
185 if( IKOT_IOKIT_OBJECT
== type
)
186 dict
= &gIOObjectPorts
;
187 else if( IKOT_IOKIT_CONNECT
== type
)
188 dict
= &gIOConnectPorts
;
193 *dict
= OSDictionary::withCapacity( 1 );
198 IOMachPort
* IOMachPort::portForObject ( OSObject
* obj
,
199 ipc_kobject_type_t type
)
201 IOMachPort
* inst
= 0;
204 IOTakeLock( gIOObjectPortLock
);
208 dict
= dictForType( type
);
212 if( (inst
= (IOMachPort
*)
213 dict
->getObject( (const OSSymbol
*) obj
))) {
219 inst
= new IOMachPort
;
220 if( inst
&& !inst
->init()) {
225 inst
->port
= iokit_alloc_object_port( obj
, type
);
228 dict
->setObject( (const OSSymbol
*) obj
, inst
);
238 IOUnlock( gIOObjectPortLock
);
243 bool IOMachPort::noMoreSendersForObject( OSObject
* obj
,
244 ipc_kobject_type_t type
, mach_port_mscount_t
* mscount
)
247 IOMachPort
* machPort
;
248 bool destroyed
= true;
250 IOTakeLock( gIOObjectPortLock
);
252 if( (dict
= dictForType( type
))) {
255 machPort
= (IOMachPort
*) dict
->getObject( (const OSSymbol
*) obj
);
257 destroyed
= (machPort
->mscount
<= *mscount
);
259 dict
->removeObject( (const OSSymbol
*) obj
);
261 *mscount
= machPort
->mscount
;
266 IOUnlock( gIOObjectPortLock
);
271 void IOMachPort::releasePortForObject( OSObject
* obj
,
272 ipc_kobject_type_t type
)
275 IOMachPort
* machPort
;
277 IOTakeLock( gIOObjectPortLock
);
279 if( (dict
= dictForType( type
))) {
281 machPort
= (IOMachPort
*) dict
->getObject( (const OSSymbol
*) obj
);
282 if( machPort
&& !machPort
->holdDestroy
)
283 dict
->removeObject( (const OSSymbol
*) obj
);
287 IOUnlock( gIOObjectPortLock
);
290 void IOMachPort::setHoldDestroy( OSObject
* obj
, ipc_kobject_type_t type
)
293 IOMachPort
* machPort
;
295 IOLockLock( gIOObjectPortLock
);
297 if( (dict
= dictForType( type
))) {
298 machPort
= (IOMachPort
*) dict
->getObject( (const OSSymbol
*) obj
);
300 machPort
->holdDestroy
= true;
303 IOLockUnlock( gIOObjectPortLock
);
306 void IOUserClient::destroyUserReferences( OSObject
* obj
)
308 IOMachPort::releasePortForObject( obj
, IKOT_IOKIT_OBJECT
);
311 // IOMachPort::releasePortForObject( obj, IKOT_IOKIT_CONNECT );
315 IOTakeLock( gIOObjectPortLock
);
318 if( (dict
= IOMachPort::dictForType( IKOT_IOKIT_CONNECT
)))
321 port
= (IOMachPort
*) dict
->getObject( (const OSSymbol
*) obj
);
325 if ((uc
= OSDynamicCast(IOUserClient
, obj
)) && uc
->mappings
)
327 dict
->setObject((const OSSymbol
*) uc
->mappings
, port
);
328 iokit_switch_object_port(port
->port
, uc
->mappings
, IKOT_IOKIT_CONNECT
);
330 uc
->mappings
->release();
333 dict
->removeObject( (const OSSymbol
*) obj
);
337 IOUnlock( gIOObjectPortLock
);
340 mach_port_name_t
IOMachPort::makeSendRightForTask( task_t task
,
341 io_object_t obj
, ipc_kobject_type_t type
)
343 return( iokit_make_send_right( task
, obj
, type
));
346 void IOMachPort::free( void )
349 iokit_destroy_object_port( port
);
353 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
355 class IOUserNotification
: public OSIterator
357 OSDeclareDefaultStructors(IOUserNotification
)
359 IONotifier
* holdNotify
;
364 virtual bool init( void );
367 virtual void setNotification( IONotifier
* obj
);
369 virtual void reset();
370 virtual bool isValid();
373 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
377 // functions called from osfmk/device/iokit_rpc.c
380 iokit_add_reference( io_object_t obj
)
387 iokit_remove_reference( io_object_t obj
)
394 iokit_port_for_object( io_object_t obj
, ipc_kobject_type_t type
)
396 IOMachPort
* machPort
;
399 if( (machPort
= IOMachPort::portForObject( obj
, type
))) {
401 port
= machPort
->port
;
403 iokit_retain_port( port
);
414 iokit_client_died( io_object_t obj
, ipc_port_t
/* port */,
415 ipc_kobject_type_t type
, mach_port_mscount_t
* mscount
)
417 IOUserClient
* client
;
419 IOUserNotification
* notify
;
421 if( !IOMachPort::noMoreSendersForObject( obj
, type
, mscount
))
422 return( kIOReturnNotReady
);
424 if( IKOT_IOKIT_CONNECT
== type
)
426 if( (client
= OSDynamicCast( IOUserClient
, obj
))) {
427 IOStatisticsClientCall();
428 client
->clientDied();
431 else if( IKOT_IOKIT_OBJECT
== type
)
433 if( (map
= OSDynamicCast( IOMemoryMap
, obj
)))
435 else if( (notify
= OSDynamicCast( IOUserNotification
, obj
)))
436 notify
->setNotification( 0 );
439 return( kIOReturnSuccess
);
444 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
446 class IOServiceUserNotification
: public IOUserNotification
448 OSDeclareDefaultStructors(IOServiceUserNotification
)
451 mach_msg_header_t msgHdr
;
452 OSNotificationHeader64 notifyHeader
;
455 enum { kMaxOutstanding
= 1024 };
460 OSObject
* lastEntry
;
465 virtual bool init( mach_port_t port
, natural_t type
,
466 void * reference
, vm_size_t referenceSize
,
470 static bool _handler( void * target
,
471 void * ref
, IOService
* newService
, IONotifier
* notifier
);
472 virtual bool handler( void * ref
, IOService
* newService
);
474 virtual OSObject
* getNextObject();
477 class IOServiceMessageUserNotification
: public IOUserNotification
479 OSDeclareDefaultStructors(IOServiceMessageUserNotification
)
482 mach_msg_header_t msgHdr
;
483 mach_msg_body_t msgBody
;
484 mach_msg_port_descriptor_t ports
[1];
485 OSNotificationHeader64 notifyHeader
__attribute__ ((packed
));
495 virtual bool init( mach_port_t port
, natural_t type
,
496 void * reference
, vm_size_t referenceSize
,
502 static IOReturn
_handler( void * target
, void * ref
,
503 UInt32 messageType
, IOService
* provider
,
504 void * messageArgument
, vm_size_t argSize
);
505 virtual IOReturn
handler( void * ref
,
506 UInt32 messageType
, IOService
* provider
,
507 void * messageArgument
, vm_size_t argSize
);
509 virtual OSObject
* getNextObject();
512 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
515 #define super OSIterator
516 OSDefineMetaClass( IOUserNotification
, OSIterator
)
517 OSDefineAbstractStructors( IOUserNotification
, OSIterator
)
519 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
521 bool IOUserNotification::init( void )
526 lock
= IOLockAlloc();
533 void IOUserNotification::free( void )
536 holdNotify
->remove();
537 // can't be in handler now
546 void IOUserNotification::setNotification( IONotifier
* notify
)
548 IONotifier
* previousNotify
;
550 IOLockLock( gIOObjectPortLock
);
552 previousNotify
= holdNotify
;
555 IOLockUnlock( gIOObjectPortLock
);
558 previousNotify
->remove();
561 void IOUserNotification::reset()
566 bool IOUserNotification::isValid()
571 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
574 #define super IOUserNotification
575 OSDefineMetaClassAndStructors(IOServiceUserNotification
, IOUserNotification
)
577 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
579 bool IOServiceUserNotification::init( mach_port_t port
, natural_t type
,
580 void * reference
, vm_size_t referenceSize
,
586 newSet
= OSArray::withCapacity( 1 );
590 if (referenceSize
> sizeof(OSAsyncReference64
))
593 msgSize
= sizeof(PingMsg
) - sizeof(OSAsyncReference64
) + referenceSize
;
594 pingMsg
= (PingMsg
*) IOMalloc( msgSize
);
598 bzero( pingMsg
, msgSize
);
600 pingMsg
->msgHdr
.msgh_remote_port
= port
;
601 pingMsg
->msgHdr
.msgh_bits
= MACH_MSGH_BITS(
602 MACH_MSG_TYPE_COPY_SEND
/*remote*/,
603 MACH_MSG_TYPE_MAKE_SEND
/*local*/);
604 pingMsg
->msgHdr
.msgh_size
= msgSize
;
605 pingMsg
->msgHdr
.msgh_id
= kOSNotificationMessageID
;
607 pingMsg
->notifyHeader
.size
= 0;
608 pingMsg
->notifyHeader
.type
= type
;
609 bcopy( reference
, pingMsg
->notifyHeader
.reference
, referenceSize
);
614 void IOServiceUserNotification::free( void )
619 OSObject
* _lastEntry
;
623 _lastEntry
= lastEntry
;
628 if( _pingMsg
&& _msgSize
) {
629 if (_pingMsg
->msgHdr
.msgh_remote_port
) {
630 iokit_release_port_send(_pingMsg
->msgHdr
.msgh_remote_port
);
632 IOFree(_pingMsg
, _msgSize
);
636 _lastEntry
->release();
642 bool IOServiceUserNotification::_handler( void * target
,
643 void * ref
, IOService
* newService
, IONotifier
* notifier
)
645 return( ((IOServiceUserNotification
*) target
)->handler( ref
, newService
));
648 bool IOServiceUserNotification::handler( void * ref
,
649 IOService
* newService
)
653 ipc_port_t port
= NULL
;
654 bool sendPing
= false;
658 count
= newSet
->getCount();
659 if( count
< kMaxOutstanding
) {
661 newSet
->setObject( newService
);
662 if( (sendPing
= (armed
&& (0 == count
))))
668 if( kIOServiceTerminatedNotificationType
== pingMsg
->notifyHeader
.type
)
669 IOMachPort::setHoldDestroy( newService
, IKOT_IOKIT_OBJECT
);
672 if( (port
= iokit_port_for_object( this, IKOT_IOKIT_OBJECT
) ))
673 pingMsg
->msgHdr
.msgh_local_port
= port
;
675 pingMsg
->msgHdr
.msgh_local_port
= NULL
;
677 kr
= mach_msg_send_from_kernel_proper( &pingMsg
->msgHdr
,
678 pingMsg
->msgHdr
.msgh_size
);
680 iokit_release_port( port
);
682 if( KERN_SUCCESS
!= kr
)
683 IOLog("%s: mach_msg_send_from_kernel_proper {%x}\n", __FILE__
, kr
);
689 OSObject
* IOServiceUserNotification::getNextObject()
697 lastEntry
->release();
699 count
= newSet
->getCount();
701 result
= newSet
->getObject( count
- 1 );
703 newSet
->removeObject( count
- 1);
715 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
717 OSDefineMetaClassAndStructors(IOServiceMessageUserNotification
, IOUserNotification
)
719 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
721 bool IOServiceMessageUserNotification::init( mach_port_t port
, natural_t type
,
722 void * reference
, vm_size_t referenceSize
, vm_size_t extraSize
,
728 if (referenceSize
> sizeof(OSAsyncReference64
))
731 clientIs64
= client64
;
733 owningPID
= proc_selfpid();
735 extraSize
+= sizeof(IOServiceInterestContent64
);
736 msgSize
= sizeof(PingMsg
) - sizeof(OSAsyncReference64
) + referenceSize
+ extraSize
;
737 pingMsg
= (PingMsg
*) IOMalloc( msgSize
);
741 bzero( pingMsg
, msgSize
);
743 pingMsg
->msgHdr
.msgh_remote_port
= port
;
744 pingMsg
->msgHdr
.msgh_bits
= MACH_MSGH_BITS_COMPLEX
746 MACH_MSG_TYPE_COPY_SEND
/*remote*/,
747 MACH_MSG_TYPE_MAKE_SEND
/*local*/);
748 pingMsg
->msgHdr
.msgh_size
= msgSize
;
749 pingMsg
->msgHdr
.msgh_id
= kOSNotificationMessageID
;
751 pingMsg
->msgBody
.msgh_descriptor_count
= 1;
753 pingMsg
->ports
[0].name
= 0;
754 pingMsg
->ports
[0].disposition
= MACH_MSG_TYPE_MAKE_SEND
;
755 pingMsg
->ports
[0].type
= MACH_MSG_PORT_DESCRIPTOR
;
757 pingMsg
->notifyHeader
.size
= extraSize
;
758 pingMsg
->notifyHeader
.type
= type
;
759 bcopy( reference
, pingMsg
->notifyHeader
.reference
, referenceSize
);
764 void IOServiceMessageUserNotification::free( void )
774 if( _pingMsg
&& _msgSize
) {
775 if (_pingMsg
->msgHdr
.msgh_remote_port
) {
776 iokit_release_port_send(_pingMsg
->msgHdr
.msgh_remote_port
);
778 IOFree( _pingMsg
, _msgSize
);
782 IOReturn
IOServiceMessageUserNotification::_handler( void * target
, void * ref
,
783 UInt32 messageType
, IOService
* provider
,
784 void * argument
, vm_size_t argSize
)
786 return( ((IOServiceMessageUserNotification
*) target
)->handler(
787 ref
, messageType
, provider
, argument
, argSize
));
790 IOReturn
IOServiceMessageUserNotification::handler( void * ref
,
791 UInt32 messageType
, IOService
* provider
,
792 void * messageArgument
, vm_size_t argSize
)
795 ipc_port_t thisPort
, providerPort
;
796 IOServiceInterestContent64
* data
= (IOServiceInterestContent64
*)
797 ((((uint8_t *) pingMsg
) + msgSize
) - pingMsg
->notifyHeader
.size
);
798 // == pingMsg->notifyHeader.content;
800 if (kIOMessageCopyClientID
== messageType
)
802 *((void **) messageArgument
) = OSNumber::withNumber(owningPID
, 32);
803 return (kIOReturnSuccess
);
806 data
->messageType
= messageType
;
810 data
->messageArgument
[0] = (io_user_reference_t
) messageArgument
;
812 argSize
= sizeof(data
->messageArgument
[0]);
815 data
->messageArgument
[0] |= (data
->messageArgument
[0] << 32);
816 argSize
= sizeof(uint32_t);
821 if( argSize
> kIOUserNotifyMaxMessageSize
)
822 argSize
= kIOUserNotifyMaxMessageSize
;
823 bcopy( messageArgument
, data
->messageArgument
, argSize
);
825 pingMsg
->msgHdr
.msgh_size
= msgSize
- pingMsg
->notifyHeader
.size
826 + sizeof( IOServiceInterestContent64
)
827 - sizeof( data
->messageArgument
)
830 providerPort
= iokit_port_for_object( provider
, IKOT_IOKIT_OBJECT
);
831 pingMsg
->ports
[0].name
= providerPort
;
832 thisPort
= iokit_port_for_object( this, IKOT_IOKIT_OBJECT
);
833 pingMsg
->msgHdr
.msgh_local_port
= thisPort
;
834 kr
= mach_msg_send_from_kernel_proper( &pingMsg
->msgHdr
,
835 pingMsg
->msgHdr
.msgh_size
);
837 iokit_release_port( thisPort
);
839 iokit_release_port( providerPort
);
841 if( KERN_SUCCESS
!= kr
)
842 IOLog("%s: mach_msg_send_from_kernel_proper {%x}\n", __FILE__
, kr
);
844 return( kIOReturnSuccess
);
847 OSObject
* IOServiceMessageUserNotification::getNextObject()
852 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
855 #define super IOService
856 OSDefineMetaClassAndAbstractStructors( IOUserClient
, IOService
)
858 void IOUserClient::initialize( void )
860 gIOObjectPortLock
= IOLockAlloc();
862 assert( gIOObjectPortLock
);
865 void IOUserClient::setAsyncReference(OSAsyncReference asyncRef
,
866 mach_port_t wakePort
,
867 void *callback
, void *refcon
)
869 asyncRef
[kIOAsyncReservedIndex
] = ((uintptr_t) wakePort
)
870 | (kIOUCAsync0Flags
& asyncRef
[kIOAsyncReservedIndex
]);
871 asyncRef
[kIOAsyncCalloutFuncIndex
] = (uintptr_t) callback
;
872 asyncRef
[kIOAsyncCalloutRefconIndex
] = (uintptr_t) refcon
;
875 void IOUserClient::setAsyncReference64(OSAsyncReference64 asyncRef
,
876 mach_port_t wakePort
,
877 mach_vm_address_t callback
, io_user_reference_t refcon
)
879 asyncRef
[kIOAsyncReservedIndex
] = ((io_user_reference_t
) wakePort
)
880 | (kIOUCAsync0Flags
& asyncRef
[kIOAsyncReservedIndex
]);
881 asyncRef
[kIOAsyncCalloutFuncIndex
] = (io_user_reference_t
) callback
;
882 asyncRef
[kIOAsyncCalloutRefconIndex
] = refcon
;
885 static OSDictionary
* CopyConsoleUser(UInt32 uid
)
888 OSDictionary
* user
= 0;
890 if ((array
= OSDynamicCast(OSArray
,
891 IORegistryEntry::getRegistryRoot()->copyProperty(gIOConsoleUsersKey
))))
893 for (unsigned int idx
= 0;
894 (user
= OSDynamicCast(OSDictionary
, array
->getObject(idx
)));
898 if ((num
= OSDynamicCast(OSNumber
, user
->getObject(gIOConsoleSessionUIDKey
)))
899 && (uid
== num
->unsigned32BitValue())) {
909 static OSDictionary
* CopyUserOnConsole(void)
912 OSDictionary
* user
= 0;
914 if ((array
= OSDynamicCast(OSArray
,
915 IORegistryEntry::getRegistryRoot()->copyProperty(gIOConsoleUsersKey
))))
917 for (unsigned int idx
= 0;
918 (user
= OSDynamicCast(OSDictionary
, array
->getObject(idx
)));
921 if (kOSBooleanTrue
== user
->getObject(gIOConsoleSessionOnConsoleKey
))
932 IOReturn
IOUserClient::clientHasPrivilege( void * securityToken
,
933 const char * privilegeName
)
936 security_token_t token
;
937 mach_msg_type_number_t count
;
943 if (!strncmp(privilegeName
, kIOClientPrivilegeForeground
,
944 sizeof(kIOClientPrivilegeForeground
)))
946 /* is graphics access denied for current task? */
947 if (proc_get_task_selfgpuacc_deny() != 0)
948 return (kIOReturnNotPrivileged
);
950 return (kIOReturnSuccess
);
953 if (!strncmp(privilegeName
, kIOClientPrivilegeConsoleSession
,
954 sizeof(kIOClientPrivilegeConsoleSession
)))
959 task
= (task_t
) securityToken
;
961 task
= current_task();
962 p
= (proc_t
) get_bsdtask_info(task
);
963 kr
= kIOReturnNotPrivileged
;
965 if (p
&& (cred
= kauth_cred_proc_ref(p
)))
967 user
= CopyUserOnConsole();
971 if ((num
= OSDynamicCast(OSNumber
, user
->getObject(gIOConsoleSessionAuditIDKey
)))
972 && (cred
->cr_audit
.as_aia_p
->ai_asid
== (au_asid_t
) num
->unsigned32BitValue()))
974 kr
= kIOReturnSuccess
;
978 kauth_cred_unref(&cred
);
983 if ((secureConsole
= !strncmp(privilegeName
, kIOClientPrivilegeSecureConsoleProcess
,
984 sizeof(kIOClientPrivilegeSecureConsoleProcess
))))
985 task
= (task_t
)((IOUCProcessToken
*)securityToken
)->token
;
987 task
= (task_t
)securityToken
;
989 count
= TASK_SECURITY_TOKEN_COUNT
;
990 kr
= task_info( task
, TASK_SECURITY_TOKEN
, (task_info_t
) &token
, &count
);
992 if (KERN_SUCCESS
!= kr
)
994 else if (!strncmp(privilegeName
, kIOClientPrivilegeAdministrator
,
995 sizeof(kIOClientPrivilegeAdministrator
))) {
996 if (0 != token
.val
[0])
997 kr
= kIOReturnNotPrivileged
;
998 } else if (!strncmp(privilegeName
, kIOClientPrivilegeLocalUser
,
999 sizeof(kIOClientPrivilegeLocalUser
))) {
1000 user
= CopyConsoleUser(token
.val
[0]);
1004 kr
= kIOReturnNotPrivileged
;
1005 } else if (secureConsole
|| !strncmp(privilegeName
, kIOClientPrivilegeConsoleUser
,
1006 sizeof(kIOClientPrivilegeConsoleUser
))) {
1007 user
= CopyConsoleUser(token
.val
[0]);
1009 if (user
->getObject(gIOConsoleSessionOnConsoleKey
) != kOSBooleanTrue
)
1010 kr
= kIOReturnNotPrivileged
;
1011 else if ( secureConsole
) {
1012 OSNumber
* pid
= OSDynamicCast(OSNumber
, user
->getObject(gIOConsoleSessionSecureInputPIDKey
));
1013 if ( pid
&& pid
->unsigned32BitValue() != ((IOUCProcessToken
*)securityToken
)->pid
)
1014 kr
= kIOReturnNotPrivileged
;
1019 kr
= kIOReturnNotPrivileged
;
1021 kr
= kIOReturnUnsupported
;
1026 bool IOUserClient::init()
1028 if (getPropertyTable() || super::init())
1034 bool IOUserClient::init(OSDictionary
* dictionary
)
1036 if (getPropertyTable() || super::init(dictionary
))
1042 bool IOUserClient::initWithTask(task_t owningTask
,
1046 if (getPropertyTable() || super::init())
1052 bool IOUserClient::initWithTask(task_t owningTask
,
1055 OSDictionary
* properties
)
1059 ok
= super::init( properties
);
1060 ok
&= initWithTask( owningTask
, securityID
, type
);
1065 bool IOUserClient::reserve()
1068 reserved
= IONew(ExpansionData
, 1);
1074 IOStatisticsRegisterCounter();
1079 void IOUserClient::free()
1082 mappings
->release();
1084 IOStatisticsUnregisterCounter();
1087 IODelete(reserved
, ExpansionData
, 1);
1092 IOReturn
IOUserClient::clientDied( void )
1094 return( clientClose());
1097 IOReturn
IOUserClient::clientClose( void )
1099 return( kIOReturnUnsupported
);
1102 IOService
* IOUserClient::getService( void )
1107 IOReturn
IOUserClient::registerNotificationPort(
1108 mach_port_t
/* port */,
1110 UInt32
/* refCon */)
1112 return( kIOReturnUnsupported
);
1115 IOReturn
IOUserClient::registerNotificationPort(
1118 io_user_reference_t refCon
)
1120 return (registerNotificationPort(port
, type
, (UInt32
) refCon
));
1123 IOReturn
IOUserClient::getNotificationSemaphore( UInt32 notification_type
,
1124 semaphore_t
* semaphore
)
1126 return( kIOReturnUnsupported
);
1129 IOReturn
IOUserClient::connectClient( IOUserClient
* /* client */ )
1131 return( kIOReturnUnsupported
);
1134 IOReturn
IOUserClient::clientMemoryForType( UInt32 type
,
1135 IOOptionBits
* options
,
1136 IOMemoryDescriptor
** memory
)
1138 return( kIOReturnUnsupported
);
1142 IOMemoryMap
* IOUserClient::mapClientMemory(
1145 IOOptionBits mapFlags
,
1146 IOVirtualAddress atAddress
)
1152 IOMemoryMap
* IOUserClient::mapClientMemory64(
1155 IOOptionBits mapFlags
,
1156 mach_vm_address_t atAddress
)
1159 IOOptionBits options
= 0;
1160 IOMemoryDescriptor
* memory
;
1161 IOMemoryMap
* map
= 0;
1163 err
= clientMemoryForType( (UInt32
) type
, &options
, &memory
);
1165 if( memory
&& (kIOReturnSuccess
== err
)) {
1167 options
= (options
& ~kIOMapUserOptionsMask
)
1168 | (mapFlags
& kIOMapUserOptionsMask
);
1169 map
= memory
->createMappingInTask( task
, atAddress
, options
);
1176 IOReturn
IOUserClient::exportObjectToClient(task_t task
,
1177 OSObject
*obj
, io_object_t
*clientObj
)
1179 mach_port_name_t name
;
1181 name
= IOMachPort::makeSendRightForTask( task
, obj
, IKOT_IOKIT_OBJECT
);
1184 *(mach_port_name_t
*)clientObj
= name
;
1185 return kIOReturnSuccess
;
1188 IOExternalMethod
* IOUserClient::getExternalMethodForIndex( UInt32
/* index */)
1193 IOExternalAsyncMethod
* IOUserClient::getExternalAsyncMethodForIndex( UInt32
/* index */)
1198 IOExternalMethod
* IOUserClient::
1199 getTargetAndMethodForIndex(IOService
**targetP
, UInt32 index
)
1201 IOExternalMethod
*method
= getExternalMethodForIndex(index
);
1204 *targetP
= (IOService
*) method
->object
;
1209 IOExternalAsyncMethod
* IOUserClient::
1210 getAsyncTargetAndMethodForIndex(IOService
** targetP
, UInt32 index
)
1212 IOExternalAsyncMethod
*method
= getExternalAsyncMethodForIndex(index
);
1215 *targetP
= (IOService
*) method
->object
;
1220 IOExternalTrap
* IOUserClient::
1221 getExternalTrapForIndex(UInt32 index
)
1226 IOExternalTrap
* IOUserClient::
1227 getTargetAndTrapForIndex(IOService
** targetP
, UInt32 index
)
1229 IOExternalTrap
*trap
= getExternalTrapForIndex(index
);
1232 *targetP
= trap
->object
;
1238 IOReturn
IOUserClient::releaseAsyncReference64(OSAsyncReference64 reference
)
1241 port
= (mach_port_t
) (reference
[0] & ~kIOUCAsync0Flags
);
1243 if (MACH_PORT_NULL
!= port
)
1244 iokit_release_port_send(port
);
1246 return (kIOReturnSuccess
);
1249 IOReturn
IOUserClient::releaseNotificationPort(mach_port_t port
)
1251 if (MACH_PORT_NULL
!= port
)
1252 iokit_release_port_send(port
);
1254 return (kIOReturnSuccess
);
1257 IOReturn
IOUserClient::sendAsyncResult(OSAsyncReference reference
,
1258 IOReturn result
, void *args
[], UInt32 numArgs
)
1260 OSAsyncReference64 reference64
;
1261 io_user_reference_t args64
[kMaxAsyncArgs
];
1264 if (numArgs
> kMaxAsyncArgs
)
1265 return kIOReturnMessageTooLarge
;
1267 for (idx
= 0; idx
< kOSAsyncRef64Count
; idx
++)
1268 reference64
[idx
] = REF64(reference
[idx
]);
1270 for (idx
= 0; idx
< numArgs
; idx
++)
1271 args64
[idx
] = REF64(args
[idx
]);
1273 return (sendAsyncResult64(reference64
, result
, args64
, numArgs
));
1276 IOReturn
IOUserClient::sendAsyncResult64(OSAsyncReference64 reference
,
1277 IOReturn result
, io_user_reference_t args
[], UInt32 numArgs
)
1281 mach_msg_header_t msgHdr
;
1286 OSNotificationHeader notifyHdr
;
1287 IOAsyncCompletionContent asyncContent
;
1288 uint32_t args
[kMaxAsyncArgs
];
1292 OSNotificationHeader64 notifyHdr
;
1293 IOAsyncCompletionContent asyncContent
;
1294 io_user_reference_t args
[kMaxAsyncArgs
] __attribute__ ((packed
));
1299 mach_port_t replyPort
;
1302 // If no reply port, do nothing.
1303 replyPort
= (mach_port_t
) (reference
[0] & ~kIOUCAsync0Flags
);
1304 if (replyPort
== MACH_PORT_NULL
)
1305 return kIOReturnSuccess
;
1307 if (numArgs
> kMaxAsyncArgs
)
1308 return kIOReturnMessageTooLarge
;
1310 replyMsg
.msgHdr
.msgh_bits
= MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND
/*remote*/,
1312 replyMsg
.msgHdr
.msgh_remote_port
= replyPort
;
1313 replyMsg
.msgHdr
.msgh_local_port
= 0;
1314 replyMsg
.msgHdr
.msgh_id
= kOSNotificationMessageID
;
1315 if (kIOUCAsync64Flag
& reference
[0])
1317 replyMsg
.msgHdr
.msgh_size
=
1318 sizeof(replyMsg
.msgHdr
) + sizeof(replyMsg
.m
.msg64
)
1319 - (kMaxAsyncArgs
- numArgs
) * sizeof(io_user_reference_t
);
1320 replyMsg
.m
.msg64
.notifyHdr
.size
= sizeof(IOAsyncCompletionContent
)
1321 + numArgs
* sizeof(io_user_reference_t
);
1322 replyMsg
.m
.msg64
.notifyHdr
.type
= kIOAsyncCompletionNotificationType
;
1323 bcopy(reference
, replyMsg
.m
.msg64
.notifyHdr
.reference
, sizeof(OSAsyncReference64
));
1325 replyMsg
.m
.msg64
.asyncContent
.result
= result
;
1327 bcopy(args
, replyMsg
.m
.msg64
.args
, numArgs
* sizeof(io_user_reference_t
));
1333 replyMsg
.msgHdr
.msgh_size
=
1334 sizeof(replyMsg
.msgHdr
) + sizeof(replyMsg
.m
.msg32
)
1335 - (kMaxAsyncArgs
- numArgs
) * sizeof(uint32_t);
1337 replyMsg
.m
.msg32
.notifyHdr
.size
= sizeof(IOAsyncCompletionContent
)
1338 + numArgs
* sizeof(uint32_t);
1339 replyMsg
.m
.msg32
.notifyHdr
.type
= kIOAsyncCompletionNotificationType
;
1341 for (idx
= 0; idx
< kOSAsyncRefCount
; idx
++)
1342 replyMsg
.m
.msg32
.notifyHdr
.reference
[idx
] = REF32(reference
[idx
]);
1344 replyMsg
.m
.msg32
.asyncContent
.result
= result
;
1346 for (idx
= 0; idx
< numArgs
; idx
++)
1347 replyMsg
.m
.msg32
.args
[idx
] = REF32(args
[idx
]);
1350 kr
= mach_msg_send_from_kernel_proper( &replyMsg
.msgHdr
,
1351 replyMsg
.msgHdr
.msgh_size
);
1352 if( KERN_SUCCESS
!= kr
)
1353 IOLog("%s: mach_msg_send_from_kernel_proper {%x}\n", __FILE__
, kr
);
1358 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1362 #define CHECK(cls,obj,out) \
1364 if( !(out = OSDynamicCast( cls, obj))) \
1365 return( kIOReturnBadArgument )
1367 /* Routine io_object_get_class */
1368 kern_return_t
is_io_object_get_class(
1370 io_name_t className
)
1372 const OSMetaClass
* my_obj
= NULL
;
1375 return( kIOReturnBadArgument
);
1377 my_obj
= object
->getMetaClass();
1379 return (kIOReturnNotFound
);
1382 strlcpy( className
, my_obj
->getClassName(), sizeof(io_name_t
));
1383 return( kIOReturnSuccess
);
1386 /* Routine io_object_get_superclass */
1387 kern_return_t
is_io_object_get_superclass(
1388 mach_port_t master_port
,
1390 io_name_t class_name
)
1392 const OSMetaClass
* my_obj
= NULL
;
1393 const OSMetaClass
* superclass
= NULL
;
1394 const OSSymbol
*my_name
= NULL
;
1395 const char *my_cstr
= NULL
;
1397 if (!obj_name
|| !class_name
)
1398 return (kIOReturnBadArgument
);
1400 if( master_port
!= master_device_port
)
1401 return( kIOReturnNotPrivileged
);
1403 my_name
= OSSymbol::withCString(obj_name
);
1406 my_obj
= OSMetaClass::getMetaClassWithName(my_name
);
1410 superclass
= my_obj
->getSuperClass();
1414 return( kIOReturnNotFound
);
1417 my_cstr
= superclass
->getClassName();
1420 strlcpy(class_name
, my_cstr
, sizeof(io_name_t
));
1421 return( kIOReturnSuccess
);
1423 return (kIOReturnNotFound
);
1426 /* Routine io_object_get_bundle_identifier */
1427 kern_return_t
is_io_object_get_bundle_identifier(
1428 mach_port_t master_port
,
1430 io_name_t bundle_name
)
1432 const OSMetaClass
* my_obj
= NULL
;
1433 const OSSymbol
*my_name
= NULL
;
1434 const OSSymbol
*identifier
= NULL
;
1435 const char *my_cstr
= NULL
;
1437 if (!obj_name
|| !bundle_name
)
1438 return (kIOReturnBadArgument
);
1440 if( master_port
!= master_device_port
)
1441 return( kIOReturnNotPrivileged
);
1443 my_name
= OSSymbol::withCString(obj_name
);
1446 my_obj
= OSMetaClass::getMetaClassWithName(my_name
);
1451 identifier
= my_obj
->getKmodName();
1454 return( kIOReturnNotFound
);
1457 my_cstr
= identifier
->getCStringNoCopy();
1459 strlcpy(bundle_name
, identifier
->getCStringNoCopy(), sizeof(io_name_t
));
1460 return( kIOReturnSuccess
);
1463 return (kIOReturnBadArgument
);
1466 /* Routine io_object_conforms_to */
1467 kern_return_t
is_io_object_conforms_to(
1469 io_name_t className
,
1470 boolean_t
*conforms
)
1473 return( kIOReturnBadArgument
);
1475 *conforms
= (0 != object
->metaCast( className
));
1476 return( kIOReturnSuccess
);
1479 /* Routine io_object_get_retain_count */
1480 kern_return_t
is_io_object_get_retain_count(
1482 uint32_t *retainCount
)
1485 return( kIOReturnBadArgument
);
1487 *retainCount
= object
->getRetainCount();
1488 return( kIOReturnSuccess
);
1491 /* Routine io_iterator_next */
1492 kern_return_t
is_io_iterator_next(
1493 io_object_t iterator
,
1494 io_object_t
*object
)
1498 CHECK( OSIterator
, iterator
, iter
);
1500 obj
= iter
->getNextObject();
1504 return( kIOReturnSuccess
);
1506 return( kIOReturnNoDevice
);
1509 /* Routine io_iterator_reset */
1510 kern_return_t
is_io_iterator_reset(
1511 io_object_t iterator
)
1513 CHECK( OSIterator
, iterator
, iter
);
1517 return( kIOReturnSuccess
);
1520 /* Routine io_iterator_is_valid */
1521 kern_return_t
is_io_iterator_is_valid(
1522 io_object_t iterator
,
1523 boolean_t
*is_valid
)
1525 CHECK( OSIterator
, iterator
, iter
);
1527 *is_valid
= iter
->isValid();
1529 return( kIOReturnSuccess
);
1532 /* Routine io_service_match_property_table */
1533 kern_return_t
is_io_service_match_property_table(
1534 io_service_t _service
,
1535 io_string_t matching
,
1536 boolean_t
*matches
)
1538 CHECK( IOService
, _service
, service
);
1542 OSDictionary
* dict
;
1544 obj
= OSUnserializeXML( matching
);
1546 if( (dict
= OSDynamicCast( OSDictionary
, obj
))) {
1547 *matches
= service
->passiveMatch( dict
);
1548 kr
= kIOReturnSuccess
;
1550 kr
= kIOReturnBadArgument
;
1558 /* Routine io_service_match_property_table_ool */
1559 kern_return_t
is_io_service_match_property_table_ool(
1560 io_object_t service
,
1561 io_buf_ptr_t matching
,
1562 mach_msg_type_number_t matchingCnt
,
1563 kern_return_t
*result
,
1564 boolean_t
*matches
)
1568 vm_map_offset_t map_data
;
1570 kr
= vm_map_copyout( kernel_map
, &map_data
, (vm_map_copy_t
) matching
);
1571 data
= CAST_DOWN(vm_offset_t
, map_data
);
1573 if( KERN_SUCCESS
== kr
) {
1574 // must return success after vm_map_copyout() succeeds
1575 *result
= is_io_service_match_property_table( service
,
1576 (char *) data
, matches
);
1577 vm_deallocate( kernel_map
, data
, matchingCnt
);
1583 /* Routine io_service_get_matching_services */
1584 kern_return_t
is_io_service_get_matching_services(
1585 mach_port_t master_port
,
1586 io_string_t matching
,
1587 io_iterator_t
*existing
)
1591 OSDictionary
* dict
;
1593 if( master_port
!= master_device_port
)
1594 return( kIOReturnNotPrivileged
);
1596 obj
= OSUnserializeXML( matching
);
1598 if( (dict
= OSDynamicCast( OSDictionary
, obj
))) {
1599 *existing
= IOService::getMatchingServices( dict
);
1600 kr
= kIOReturnSuccess
;
1602 kr
= kIOReturnBadArgument
;
1610 /* Routine io_service_get_matching_services_ool */
1611 kern_return_t
is_io_service_get_matching_services_ool(
1612 mach_port_t master_port
,
1613 io_buf_ptr_t matching
,
1614 mach_msg_type_number_t matchingCnt
,
1615 kern_return_t
*result
,
1616 io_object_t
*existing
)
1620 vm_map_offset_t map_data
;
1622 kr
= vm_map_copyout( kernel_map
, &map_data
, (vm_map_copy_t
) matching
);
1623 data
= CAST_DOWN(vm_offset_t
, map_data
);
1625 if( KERN_SUCCESS
== kr
) {
1626 // must return success after vm_map_copyout() succeeds
1627 *result
= is_io_service_get_matching_services( master_port
,
1628 (char *) data
, existing
);
1629 vm_deallocate( kernel_map
, data
, matchingCnt
);
1636 /* Routine io_service_get_matching_service */
1637 kern_return_t
is_io_service_get_matching_service(
1638 mach_port_t master_port
,
1639 io_string_t matching
,
1640 io_service_t
*service
)
1644 OSDictionary
* dict
;
1646 if( master_port
!= master_device_port
)
1647 return( kIOReturnNotPrivileged
);
1649 obj
= OSUnserializeXML( matching
);
1651 if( (dict
= OSDynamicCast( OSDictionary
, obj
))) {
1652 *service
= IOService::copyMatchingService( dict
);
1653 kr
= *service
? kIOReturnSuccess
: kIOReturnNotFound
;
1655 kr
= kIOReturnBadArgument
;
1663 /* Routine io_service_get_matching_services_ool */
1664 kern_return_t
is_io_service_get_matching_service_ool(
1665 mach_port_t master_port
,
1666 io_buf_ptr_t matching
,
1667 mach_msg_type_number_t matchingCnt
,
1668 kern_return_t
*result
,
1669 io_object_t
*service
)
1673 vm_map_offset_t map_data
;
1675 kr
= vm_map_copyout( kernel_map
, &map_data
, (vm_map_copy_t
) matching
);
1676 data
= CAST_DOWN(vm_offset_t
, map_data
);
1678 if( KERN_SUCCESS
== kr
) {
1679 // must return success after vm_map_copyout() succeeds
1680 *result
= is_io_service_get_matching_service( master_port
,
1681 (char *) data
, service
);
1682 vm_deallocate( kernel_map
, data
, matchingCnt
);
1689 static kern_return_t
internal_io_service_add_notification(
1690 mach_port_t master_port
,
1691 io_name_t notification_type
,
1692 io_string_t matching
,
1695 vm_size_t referenceSize
,
1697 io_object_t
* notification
)
1699 IOServiceUserNotification
* userNotify
= 0;
1700 IONotifier
* notify
= 0;
1701 const OSSymbol
* sym
;
1702 OSDictionary
* dict
;
1704 unsigned long int userMsgType
;
1707 if( master_port
!= master_device_port
)
1708 return( kIOReturnNotPrivileged
);
1711 err
= kIOReturnNoResources
;
1713 if( !(sym
= OSSymbol::withCString( notification_type
)))
1714 err
= kIOReturnNoResources
;
1716 if( !(dict
= OSDynamicCast( OSDictionary
,
1717 OSUnserializeXML( matching
)))) {
1718 err
= kIOReturnBadArgument
;
1722 if( (sym
== gIOPublishNotification
)
1723 || (sym
== gIOFirstPublishNotification
))
1724 userMsgType
= kIOServicePublishNotificationType
;
1725 else if( (sym
== gIOMatchedNotification
)
1726 || (sym
== gIOFirstMatchNotification
))
1727 userMsgType
= kIOServiceMatchedNotificationType
;
1728 else if( sym
== gIOTerminatedNotification
)
1729 userMsgType
= kIOServiceTerminatedNotificationType
;
1731 userMsgType
= kLastIOKitNotificationType
;
1733 userNotify
= new IOServiceUserNotification
;
1735 if( userNotify
&& !userNotify
->init( port
, userMsgType
,
1736 reference
, referenceSize
, client64
)) {
1737 iokit_release_port_send(port
);
1738 userNotify
->release();
1744 notify
= IOService::addMatchingNotification( sym
, dict
,
1745 &userNotify
->_handler
, userNotify
);
1747 *notification
= userNotify
;
1748 userNotify
->setNotification( notify
);
1749 err
= kIOReturnSuccess
;
1751 err
= kIOReturnUnsupported
;
1764 /* Routine io_service_add_notification */
1765 kern_return_t
is_io_service_add_notification(
1766 mach_port_t master_port
,
1767 io_name_t notification_type
,
1768 io_string_t matching
,
1770 io_async_ref_t reference
,
1771 mach_msg_type_number_t referenceCnt
,
1772 io_object_t
* notification
)
1774 return (internal_io_service_add_notification(master_port
, notification_type
,
1775 matching
, port
, &reference
[0], sizeof(io_async_ref_t
),
1776 false, notification
));
1779 /* Routine io_service_add_notification_64 */
1780 kern_return_t
is_io_service_add_notification_64(
1781 mach_port_t master_port
,
1782 io_name_t notification_type
,
1783 io_string_t matching
,
1784 mach_port_t wake_port
,
1785 io_async_ref64_t reference
,
1786 mach_msg_type_number_t referenceCnt
,
1787 io_object_t
*notification
)
1789 return (internal_io_service_add_notification(master_port
, notification_type
,
1790 matching
, wake_port
, &reference
[0], sizeof(io_async_ref64_t
),
1791 true, notification
));
1795 static kern_return_t
internal_io_service_add_notification_ool(
1796 mach_port_t master_port
,
1797 io_name_t notification_type
,
1798 io_buf_ptr_t matching
,
1799 mach_msg_type_number_t matchingCnt
,
1800 mach_port_t wake_port
,
1802 vm_size_t referenceSize
,
1804 kern_return_t
*result
,
1805 io_object_t
*notification
)
1809 vm_map_offset_t map_data
;
1811 kr
= vm_map_copyout( kernel_map
, &map_data
, (vm_map_copy_t
) matching
);
1812 data
= CAST_DOWN(vm_offset_t
, map_data
);
1814 if( KERN_SUCCESS
== kr
) {
1815 // must return success after vm_map_copyout() succeeds
1816 *result
= internal_io_service_add_notification( master_port
, notification_type
,
1817 (char *) data
, wake_port
, reference
, referenceSize
, client64
, notification
);
1818 vm_deallocate( kernel_map
, data
, matchingCnt
);
1824 /* Routine io_service_add_notification_ool */
1825 kern_return_t
is_io_service_add_notification_ool(
1826 mach_port_t master_port
,
1827 io_name_t notification_type
,
1828 io_buf_ptr_t matching
,
1829 mach_msg_type_number_t matchingCnt
,
1830 mach_port_t wake_port
,
1831 io_async_ref_t reference
,
1832 mach_msg_type_number_t referenceCnt
,
1833 kern_return_t
*result
,
1834 io_object_t
*notification
)
1836 return (internal_io_service_add_notification_ool(master_port
, notification_type
,
1837 matching
, matchingCnt
, wake_port
, &reference
[0], sizeof(io_async_ref_t
),
1838 false, result
, notification
));
1841 /* Routine io_service_add_notification_ool_64 */
1842 kern_return_t
is_io_service_add_notification_ool_64(
1843 mach_port_t master_port
,
1844 io_name_t notification_type
,
1845 io_buf_ptr_t matching
,
1846 mach_msg_type_number_t matchingCnt
,
1847 mach_port_t wake_port
,
1848 io_async_ref64_t reference
,
1849 mach_msg_type_number_t referenceCnt
,
1850 kern_return_t
*result
,
1851 io_object_t
*notification
)
1853 return (internal_io_service_add_notification_ool(master_port
, notification_type
,
1854 matching
, matchingCnt
, wake_port
, &reference
[0], sizeof(io_async_ref64_t
),
1855 true, result
, notification
));
1858 /* Routine io_service_add_notification_old */
1859 kern_return_t
is_io_service_add_notification_old(
1860 mach_port_t master_port
,
1861 io_name_t notification_type
,
1862 io_string_t matching
,
1864 // for binary compatibility reasons, this must be natural_t for ILP32
1866 io_object_t
* notification
)
1868 return( is_io_service_add_notification( master_port
, notification_type
,
1869 matching
, port
, &ref
, 1, notification
));
1873 static kern_return_t
internal_io_service_add_interest_notification(
1874 io_object_t _service
,
1875 io_name_t type_of_interest
,
1878 vm_size_t referenceSize
,
1880 io_object_t
* notification
)
1883 IOServiceMessageUserNotification
* userNotify
= 0;
1884 IONotifier
* notify
= 0;
1885 const OSSymbol
* sym
;
1888 CHECK( IOService
, _service
, service
);
1890 err
= kIOReturnNoResources
;
1891 if( (sym
= OSSymbol::withCString( type_of_interest
))) do {
1893 userNotify
= new IOServiceMessageUserNotification
;
1895 if( userNotify
&& !userNotify
->init( port
, kIOServiceMessageNotificationType
,
1896 reference
, referenceSize
,
1897 kIOUserNotifyMaxMessageSize
,
1899 iokit_release_port_send(port
);
1900 userNotify
->release();
1906 notify
= service
->registerInterest( sym
,
1907 &userNotify
->_handler
, userNotify
);
1909 *notification
= userNotify
;
1910 userNotify
->setNotification( notify
);
1911 err
= kIOReturnSuccess
;
1913 err
= kIOReturnUnsupported
;
1922 /* Routine io_service_add_message_notification */
1923 kern_return_t
is_io_service_add_interest_notification(
1924 io_object_t service
,
1925 io_name_t type_of_interest
,
1927 io_async_ref_t reference
,
1928 mach_msg_type_number_t referenceCnt
,
1929 io_object_t
* notification
)
1931 return (internal_io_service_add_interest_notification(service
, type_of_interest
,
1932 port
, &reference
[0], sizeof(io_async_ref_t
), false, notification
));
1935 /* Routine io_service_add_interest_notification_64 */
1936 kern_return_t
is_io_service_add_interest_notification_64(
1937 io_object_t service
,
1938 io_name_t type_of_interest
,
1939 mach_port_t wake_port
,
1940 io_async_ref64_t reference
,
1941 mach_msg_type_number_t referenceCnt
,
1942 io_object_t
*notification
)
1944 return (internal_io_service_add_interest_notification(service
, type_of_interest
,
1945 wake_port
, &reference
[0], sizeof(io_async_ref64_t
), true, notification
));
1949 /* Routine io_service_acknowledge_notification */
1950 kern_return_t
is_io_service_acknowledge_notification(
1951 io_object_t _service
,
1952 natural_t notify_ref
,
1953 natural_t response
)
1955 CHECK( IOService
, _service
, service
);
1957 return( service
->acknowledgeNotification( (IONotificationRef
) notify_ref
,
1958 (IOOptionBits
) response
));
1962 /* Routine io_connect_get_semaphore */
1963 kern_return_t
is_io_connect_get_notification_semaphore(
1964 io_connect_t connection
,
1965 natural_t notification_type
,
1966 semaphore_t
*semaphore
)
1968 CHECK( IOUserClient
, connection
, client
);
1970 IOStatisticsClientCall();
1971 return( client
->getNotificationSemaphore( (UInt32
) notification_type
,
1975 /* Routine io_registry_get_root_entry */
1976 kern_return_t
is_io_registry_get_root_entry(
1977 mach_port_t master_port
,
1980 IORegistryEntry
* entry
;
1982 if( master_port
!= master_device_port
)
1983 return( kIOReturnNotPrivileged
);
1985 entry
= IORegistryEntry::getRegistryRoot();
1990 return( kIOReturnSuccess
);
1993 /* Routine io_registry_create_iterator */
1994 kern_return_t
is_io_registry_create_iterator(
1995 mach_port_t master_port
,
1998 io_object_t
*iterator
)
2000 if( master_port
!= master_device_port
)
2001 return( kIOReturnNotPrivileged
);
2003 *iterator
= IORegistryIterator::iterateOver(
2004 IORegistryEntry::getPlane( plane
), options
);
2006 return( *iterator
? kIOReturnSuccess
: kIOReturnBadArgument
);
2009 /* Routine io_registry_entry_create_iterator */
2010 kern_return_t
is_io_registry_entry_create_iterator(
2011 io_object_t registry_entry
,
2014 io_object_t
*iterator
)
2016 CHECK( IORegistryEntry
, registry_entry
, entry
);
2018 *iterator
= IORegistryIterator::iterateOver( entry
,
2019 IORegistryEntry::getPlane( plane
), options
);
2021 return( *iterator
? kIOReturnSuccess
: kIOReturnBadArgument
);
2024 /* Routine io_registry_iterator_enter */
2025 kern_return_t
is_io_registry_iterator_enter_entry(
2026 io_object_t iterator
)
2028 CHECK( IORegistryIterator
, iterator
, iter
);
2032 return( kIOReturnSuccess
);
2035 /* Routine io_registry_iterator_exit */
2036 kern_return_t
is_io_registry_iterator_exit_entry(
2037 io_object_t iterator
)
2041 CHECK( IORegistryIterator
, iterator
, iter
);
2043 didIt
= iter
->exitEntry();
2045 return( didIt
? kIOReturnSuccess
: kIOReturnNoDevice
);
2048 /* Routine io_registry_entry_from_path */
2049 kern_return_t
is_io_registry_entry_from_path(
2050 mach_port_t master_port
,
2052 io_object_t
*registry_entry
)
2054 IORegistryEntry
* entry
;
2056 if( master_port
!= master_device_port
)
2057 return( kIOReturnNotPrivileged
);
2059 entry
= IORegistryEntry::fromPath( path
);
2061 *registry_entry
= entry
;
2063 return( kIOReturnSuccess
);
2066 /* Routine io_registry_entry_in_plane */
2067 kern_return_t
is_io_registry_entry_in_plane(
2068 io_object_t registry_entry
,
2070 boolean_t
*inPlane
)
2072 CHECK( IORegistryEntry
, registry_entry
, entry
);
2074 *inPlane
= entry
->inPlane( IORegistryEntry::getPlane( plane
));
2076 return( kIOReturnSuccess
);
2080 /* Routine io_registry_entry_get_path */
2081 kern_return_t
is_io_registry_entry_get_path(
2082 io_object_t registry_entry
,
2087 CHECK( IORegistryEntry
, registry_entry
, entry
);
2089 length
= sizeof( io_string_t
);
2090 if( entry
->getPath( path
, &length
, IORegistryEntry::getPlane( plane
)))
2091 return( kIOReturnSuccess
);
2093 return( kIOReturnBadArgument
);
2097 /* Routine io_registry_entry_get_name */
2098 kern_return_t
is_io_registry_entry_get_name(
2099 io_object_t registry_entry
,
2102 CHECK( IORegistryEntry
, registry_entry
, entry
);
2104 strncpy( name
, entry
->getName(), sizeof( io_name_t
));
2106 return( kIOReturnSuccess
);
2109 /* Routine io_registry_entry_get_name_in_plane */
2110 kern_return_t
is_io_registry_entry_get_name_in_plane(
2111 io_object_t registry_entry
,
2112 io_name_t planeName
,
2115 const IORegistryPlane
* plane
;
2116 CHECK( IORegistryEntry
, registry_entry
, entry
);
2119 plane
= IORegistryEntry::getPlane( planeName
);
2123 strncpy( name
, entry
->getName( plane
), sizeof( io_name_t
));
2125 return( kIOReturnSuccess
);
2128 /* Routine io_registry_entry_get_location_in_plane */
2129 kern_return_t
is_io_registry_entry_get_location_in_plane(
2130 io_object_t registry_entry
,
2131 io_name_t planeName
,
2132 io_name_t location
)
2134 const IORegistryPlane
* plane
;
2135 CHECK( IORegistryEntry
, registry_entry
, entry
);
2138 plane
= IORegistryEntry::getPlane( planeName
);
2142 const char * cstr
= entry
->getLocation( plane
);
2145 strncpy( location
, cstr
, sizeof( io_name_t
));
2146 return( kIOReturnSuccess
);
2148 return( kIOReturnNotFound
);
2151 /* Routine io_registry_entry_get_registry_entry_id */
2152 kern_return_t
is_io_registry_entry_get_registry_entry_id(
2153 io_object_t registry_entry
,
2154 uint64_t *entry_id
)
2156 CHECK( IORegistryEntry
, registry_entry
, entry
);
2158 *entry_id
= entry
->getRegistryEntryID();
2160 return (kIOReturnSuccess
);
2163 // Create a vm_map_copy_t or kalloc'ed data for memory
2164 // to be copied out. ipc will free after the copyout.
2166 static kern_return_t
copyoutkdata( const void * data
, vm_size_t len
,
2167 io_buf_ptr_t
* buf
)
2172 err
= vm_map_copyin( kernel_map
, CAST_USER_ADDR_T(data
), len
,
2173 false /* src_destroy */, ©
);
2175 assert( err
== KERN_SUCCESS
);
2176 if( err
== KERN_SUCCESS
)
2177 *buf
= (char *) copy
;
2182 /* Routine io_registry_entry_get_property */
2183 kern_return_t
is_io_registry_entry_get_property_bytes(
2184 io_object_t registry_entry
,
2185 io_name_t property_name
,
2186 io_struct_inband_t buf
,
2187 mach_msg_type_number_t
*dataCnt
)
2195 unsigned int len
= 0;
2196 const void * bytes
= 0;
2197 IOReturn ret
= kIOReturnSuccess
;
2199 CHECK( IORegistryEntry
, registry_entry
, entry
);
2201 obj
= entry
->copyProperty(property_name
);
2203 return( kIOReturnNoResources
);
2205 // One day OSData will be a common container base class
2207 if( (data
= OSDynamicCast( OSData
, obj
))) {
2208 len
= data
->getLength();
2209 bytes
= data
->getBytesNoCopy();
2211 } else if( (str
= OSDynamicCast( OSString
, obj
))) {
2212 len
= str
->getLength() + 1;
2213 bytes
= str
->getCStringNoCopy();
2215 } else if( (boo
= OSDynamicCast( OSBoolean
, obj
))) {
2216 len
= boo
->isTrue() ? sizeof("Yes") : sizeof("No");
2217 bytes
= boo
->isTrue() ? "Yes" : "No";
2219 } else if( (off
= OSDynamicCast( OSNumber
, obj
))) {
2220 offsetBytes
= off
->unsigned64BitValue();
2221 len
= off
->numberOfBytes();
2222 bytes
= &offsetBytes
;
2223 #ifdef __BIG_ENDIAN__
2224 bytes
= (const void *)
2225 (((UInt32
) bytes
) + (sizeof( UInt64
) - len
));
2229 ret
= kIOReturnBadArgument
;
2233 ret
= kIOReturnIPCError
;
2236 bcopy( bytes
, buf
, len
);
2245 /* Routine io_registry_entry_get_property */
2246 kern_return_t
is_io_registry_entry_get_property(
2247 io_object_t registry_entry
,
2248 io_name_t property_name
,
2249 io_buf_ptr_t
*properties
,
2250 mach_msg_type_number_t
*propertiesCnt
)
2256 CHECK( IORegistryEntry
, registry_entry
, entry
);
2258 obj
= entry
->copyProperty(property_name
);
2260 return( kIOReturnNotFound
);
2262 OSSerialize
* s
= OSSerialize::withCapacity(4096);
2265 return( kIOReturnNoMemory
);
2269 if( obj
->serialize( s
)) {
2270 len
= s
->getLength();
2271 *propertiesCnt
= len
;
2272 err
= copyoutkdata( s
->text(), len
, properties
);
2275 err
= kIOReturnUnsupported
;
2283 /* Routine io_registry_entry_get_property_recursively */
2284 kern_return_t
is_io_registry_entry_get_property_recursively(
2285 io_object_t registry_entry
,
2287 io_name_t property_name
,
2289 io_buf_ptr_t
*properties
,
2290 mach_msg_type_number_t
*propertiesCnt
)
2296 CHECK( IORegistryEntry
, registry_entry
, entry
);
2298 obj
= entry
->copyProperty( property_name
,
2299 IORegistryEntry::getPlane( plane
), options
);
2301 return( kIOReturnNotFound
);
2303 OSSerialize
* s
= OSSerialize::withCapacity(4096);
2306 return( kIOReturnNoMemory
);
2311 if( obj
->serialize( s
)) {
2312 len
= s
->getLength();
2313 *propertiesCnt
= len
;
2314 err
= copyoutkdata( s
->text(), len
, properties
);
2317 err
= kIOReturnUnsupported
;
2325 /* Routine io_registry_entry_get_properties */
2326 kern_return_t
is_io_registry_entry_get_properties(
2327 io_object_t registry_entry
,
2328 io_buf_ptr_t
*properties
,
2329 mach_msg_type_number_t
*propertiesCnt
)
2334 CHECK( IORegistryEntry
, registry_entry
, entry
);
2336 OSSerialize
* s
= OSSerialize::withCapacity(4096);
2338 return( kIOReturnNoMemory
);
2342 if( entry
->serializeProperties( s
)) {
2343 len
= s
->getLength();
2344 *propertiesCnt
= len
;
2345 err
= copyoutkdata( s
->text(), len
, properties
);
2348 err
= kIOReturnUnsupported
;
2355 /* Routine io_registry_entry_set_properties */
2356 kern_return_t is_io_registry_entry_set_properties
2358 io_object_t registry_entry
,
2359 io_buf_ptr_t properties
,
2360 mach_msg_type_number_t propertiesCnt
,
2361 kern_return_t
* result
)
2367 vm_map_offset_t map_data
;
2369 CHECK( IORegistryEntry
, registry_entry
, entry
);
2371 err
= vm_map_copyout( kernel_map
, &map_data
, (vm_map_copy_t
) properties
);
2372 data
= CAST_DOWN(vm_offset_t
, map_data
);
2374 if( KERN_SUCCESS
== err
) {
2376 // must return success after vm_map_copyout() succeeds
2377 obj
= OSUnserializeXML( (const char *) data
);
2378 vm_deallocate( kernel_map
, data
, propertiesCnt
);
2381 res
= kIOReturnBadArgument
;
2383 else if (0 != mac_iokit_check_set_properties(kauth_cred_get(),
2384 registry_entry
, obj
))
2385 res
= kIOReturnNotPermitted
;
2388 res
= entry
->setProperties( obj
);
2398 /* Routine io_registry_entry_get_child_iterator */
2399 kern_return_t
is_io_registry_entry_get_child_iterator(
2400 io_object_t registry_entry
,
2402 io_object_t
*iterator
)
2404 CHECK( IORegistryEntry
, registry_entry
, entry
);
2406 *iterator
= entry
->getChildIterator(
2407 IORegistryEntry::getPlane( plane
));
2409 return( kIOReturnSuccess
);
2412 /* Routine io_registry_entry_get_parent_iterator */
2413 kern_return_t
is_io_registry_entry_get_parent_iterator(
2414 io_object_t registry_entry
,
2416 io_object_t
*iterator
)
2418 CHECK( IORegistryEntry
, registry_entry
, entry
);
2420 *iterator
= entry
->getParentIterator(
2421 IORegistryEntry::getPlane( plane
));
2423 return( kIOReturnSuccess
);
2426 /* Routine io_service_get_busy_state */
2427 kern_return_t
is_io_service_get_busy_state(
2428 io_object_t _service
,
2429 uint32_t *busyState
)
2431 CHECK( IOService
, _service
, service
);
2433 *busyState
= service
->getBusyState();
2435 return( kIOReturnSuccess
);
2438 /* Routine io_service_get_state */
2439 kern_return_t
is_io_service_get_state(
2440 io_object_t _service
,
2442 uint32_t *busy_state
,
2443 uint64_t *accumulated_busy_time
)
2445 CHECK( IOService
, _service
, service
);
2447 *state
= service
->getState();
2448 *busy_state
= service
->getBusyState();
2449 *accumulated_busy_time
= service
->getAccumulatedBusyTime();
2451 return( kIOReturnSuccess
);
2454 /* Routine io_service_wait_quiet */
2455 kern_return_t
is_io_service_wait_quiet(
2456 io_object_t _service
,
2457 mach_timespec_t wait_time
)
2461 CHECK( IOService
, _service
, service
);
2463 timeoutNS
= wait_time
.tv_sec
;
2464 timeoutNS
*= kSecondScale
;
2465 timeoutNS
+= wait_time
.tv_nsec
;
2467 return( service
->waitQuiet(timeoutNS
) );
2470 /* Routine io_service_request_probe */
2471 kern_return_t
is_io_service_request_probe(
2472 io_object_t _service
,
2475 CHECK( IOService
, _service
, service
);
2477 return( service
->requestProbe( options
));
2480 /* Routine io_service_open_ndr */
2481 kern_return_t
is_io_service_open_extended(
2482 io_object_t _service
,
2484 uint32_t connect_type
,
2486 io_buf_ptr_t properties
,
2487 mach_msg_type_number_t propertiesCnt
,
2488 kern_return_t
* result
,
2489 io_object_t
*connection
)
2491 IOUserClient
* client
= 0;
2492 kern_return_t err
= KERN_SUCCESS
;
2493 IOReturn res
= kIOReturnSuccess
;
2494 OSDictionary
* propertiesDict
= 0;
2496 bool disallowAccess
;
2498 CHECK( IOService
, _service
, service
);
2506 vm_map_offset_t map_data
;
2508 err
= vm_map_copyout( kernel_map
, &map_data
, (vm_map_copy_t
) properties
);
2510 data
= CAST_DOWN(vm_offset_t
, map_data
);
2511 if (KERN_SUCCESS
== err
)
2513 // must return success after vm_map_copyout() succeeds
2514 obj
= OSUnserializeXML( (const char *) data
);
2515 vm_deallocate( kernel_map
, data
, propertiesCnt
);
2516 propertiesDict
= OSDynamicCast(OSDictionary
, obj
);
2517 if (!propertiesDict
)
2519 res
= kIOReturnBadArgument
;
2524 if (kIOReturnSuccess
!= res
)
2528 crossEndian
= (ndr
.int_rep
!= NDR_record
.int_rep
);
2531 if (!propertiesDict
)
2532 propertiesDict
= OSDictionary::withCapacity(4);
2533 OSData
* data
= OSData::withBytes(&ndr
, sizeof(ndr
));
2537 propertiesDict
->setObject(kIOUserClientCrossEndianKey
, data
);
2542 res
= service
->newUserClient( owningTask
, (void *) owningTask
,
2543 connect_type
, propertiesDict
, &client
);
2546 propertiesDict
->release();
2548 if (res
== kIOReturnSuccess
)
2550 assert( OSDynamicCast(IOUserClient
, client
) );
2552 disallowAccess
= (crossEndian
2553 && (kOSBooleanTrue
!= service
->getProperty(kIOUserClientCrossEndianCompatibleKey
))
2554 && (kOSBooleanTrue
!= client
->getProperty(kIOUserClientCrossEndianCompatibleKey
)));
2555 if (disallowAccess
) res
= kIOReturnUnsupported
;
2557 else if (0 != mac_iokit_check_open(kauth_cred_get(), client
, connect_type
))
2558 res
= kIOReturnNotPermitted
;
2560 if (kIOReturnSuccess
!= res
)
2562 IOStatisticsClientCall();
2563 client
->clientClose();
2568 client
->sharedInstance
= (0 != client
->getProperty(kIOUserClientSharedInstanceKey
));
2569 OSString
* creatorName
= IOCopyLogNameForPID(proc_selfpid());
2572 client
->setProperty(kIOUserClientCreatorKey
, creatorName
);
2573 creatorName
->release();
2579 *connection
= client
;
2585 /* Routine io_service_close */
2586 kern_return_t
is_io_service_close(
2587 io_object_t connection
)
2590 if ((mappings
= OSDynamicCast(OSSet
, connection
)))
2591 return( kIOReturnSuccess
);
2593 CHECK( IOUserClient
, connection
, client
);
2595 IOStatisticsClientCall();
2596 client
->clientClose();
2598 return( kIOReturnSuccess
);
2601 /* Routine io_connect_get_service */
2602 kern_return_t
is_io_connect_get_service(
2603 io_object_t connection
,
2604 io_object_t
*service
)
2606 IOService
* theService
;
2608 CHECK( IOUserClient
, connection
, client
);
2610 theService
= client
->getService();
2612 theService
->retain();
2614 *service
= theService
;
2616 return( theService
? kIOReturnSuccess
: kIOReturnUnsupported
);
2619 /* Routine io_connect_set_notification_port */
2620 kern_return_t
is_io_connect_set_notification_port(
2621 io_object_t connection
,
2622 uint32_t notification_type
,
2626 CHECK( IOUserClient
, connection
, client
);
2628 IOStatisticsClientCall();
2629 return( client
->registerNotificationPort( port
, notification_type
,
2630 (io_user_reference_t
) reference
));
2633 /* Routine io_connect_set_notification_port */
2634 kern_return_t
is_io_connect_set_notification_port_64(
2635 io_object_t connection
,
2636 uint32_t notification_type
,
2638 io_user_reference_t reference
)
2640 CHECK( IOUserClient
, connection
, client
);
2642 IOStatisticsClientCall();
2643 return( client
->registerNotificationPort( port
, notification_type
,
2647 /* Routine io_connect_map_memory_into_task */
2648 kern_return_t is_io_connect_map_memory_into_task
2650 io_connect_t connection
,
2651 uint32_t memory_type
,
2653 mach_vm_address_t
*address
,
2654 mach_vm_size_t
*size
,
2661 CHECK( IOUserClient
, connection
, client
);
2663 IOStatisticsClientCall();
2664 map
= client
->mapClientMemory64( memory_type
, into_task
, flags
, *address
);
2667 *address
= map
->getAddress();
2669 *size
= map
->getSize();
2671 if( client
->sharedInstance
2672 || (into_task
!= current_task())) {
2673 // push a name out to the task owning the map,
2674 // so we can clean up maps
2675 mach_port_name_t name __unused
=
2676 IOMachPort::makeSendRightForTask(
2677 into_task
, map
, IKOT_IOKIT_OBJECT
);
2681 // keep it with the user client
2682 IOLockLock( gIOObjectPortLock
);
2683 if( 0 == client
->mappings
)
2684 client
->mappings
= OSSet::withCapacity(2);
2685 if( client
->mappings
)
2686 client
->mappings
->setObject( map
);
2687 IOLockUnlock( gIOObjectPortLock
);
2690 err
= kIOReturnSuccess
;
2693 err
= kIOReturnBadArgument
;
2698 /* Routine is_io_connect_map_memory */
2699 kern_return_t
is_io_connect_map_memory(
2700 io_object_t connect
,
2703 vm_address_t
* mapAddr
,
2704 vm_size_t
* mapSize
,
2708 mach_vm_address_t address
;
2709 mach_vm_size_t size
;
2711 address
= SCALAR64(*mapAddr
);
2712 size
= SCALAR64(*mapSize
);
2714 err
= is_io_connect_map_memory_into_task(connect
, type
, task
, &address
, &size
, flags
);
2716 *mapAddr
= SCALAR32(address
);
2717 *mapSize
= SCALAR32(size
);
2724 IOMemoryMap
* IOUserClient::removeMappingForDescriptor(IOMemoryDescriptor
* mem
)
2727 IOMemoryMap
* map
= 0;
2729 IOLockLock(gIOObjectPortLock
);
2731 iter
= OSCollectionIterator::withCollection(mappings
);
2734 while ((map
= OSDynamicCast(IOMemoryMap
, iter
->getNextObject())))
2736 if(mem
== map
->getMemoryDescriptor())
2739 mappings
->removeObject(map
);
2746 IOLockUnlock(gIOObjectPortLock
);
2753 /* Routine io_connect_unmap_memory_from_task */
2754 kern_return_t is_io_connect_unmap_memory_from_task
2756 io_connect_t connection
,
2757 uint32_t memory_type
,
2759 mach_vm_address_t address
)
2762 IOOptionBits options
= 0;
2763 IOMemoryDescriptor
* memory
;
2766 CHECK( IOUserClient
, connection
, client
);
2768 IOStatisticsClientCall();
2769 err
= client
->clientMemoryForType( (UInt32
) memory_type
, &options
, &memory
);
2771 if( memory
&& (kIOReturnSuccess
== err
)) {
2773 options
= (options
& ~kIOMapUserOptionsMask
)
2774 | kIOMapAnywhere
| kIOMapReference
;
2776 map
= memory
->createMappingInTask( from_task
, address
, options
);
2780 IOLockLock( gIOObjectPortLock
);
2781 if( client
->mappings
)
2782 client
->mappings
->removeObject( map
);
2783 IOLockUnlock( gIOObjectPortLock
);
2785 mach_port_name_t name
= 0;
2786 if (from_task
!= current_task())
2787 name
= IOMachPort::makeSendRightForTask( from_task
, map
, IKOT_IOKIT_OBJECT
);
2790 map
->userClientUnmap();
2791 err
= iokit_mod_send_right( from_task
, name
, -2 );
2792 err
= kIOReturnSuccess
;
2795 IOMachPort::releasePortForObject( map
, IKOT_IOKIT_OBJECT
);
2796 if (from_task
== current_task())
2800 err
= kIOReturnBadArgument
;
2806 kern_return_t
is_io_connect_unmap_memory(
2807 io_object_t connect
,
2810 vm_address_t mapAddr
)
2813 mach_vm_address_t address
;
2815 address
= SCALAR64(mapAddr
);
2817 err
= is_io_connect_unmap_memory_from_task(connect
, type
, task
, mapAddr
);
2823 /* Routine io_connect_add_client */
2824 kern_return_t
is_io_connect_add_client(
2825 io_object_t connection
,
2826 io_object_t connect_to
)
2828 CHECK( IOUserClient
, connection
, client
);
2829 CHECK( IOUserClient
, connect_to
, to
);
2831 IOStatisticsClientCall();
2832 return( client
->connectClient( to
) );
2836 /* Routine io_connect_set_properties */
2837 kern_return_t
is_io_connect_set_properties(
2838 io_object_t connection
,
2839 io_buf_ptr_t properties
,
2840 mach_msg_type_number_t propertiesCnt
,
2841 kern_return_t
* result
)
2843 return( is_io_registry_entry_set_properties( connection
, properties
, propertiesCnt
, result
));
2846 /* Routine io_user_client_method */
2847 kern_return_t is_io_connect_method_var_output
2849 io_connect_t connection
,
2851 io_scalar_inband64_t scalar_input
,
2852 mach_msg_type_number_t scalar_inputCnt
,
2853 io_struct_inband_t inband_input
,
2854 mach_msg_type_number_t inband_inputCnt
,
2855 mach_vm_address_t ool_input
,
2856 mach_vm_size_t ool_input_size
,
2857 io_struct_inband_t inband_output
,
2858 mach_msg_type_number_t
*inband_outputCnt
,
2859 io_scalar_inband64_t scalar_output
,
2860 mach_msg_type_number_t
*scalar_outputCnt
,
2861 io_buf_ptr_t
*var_output
,
2862 mach_msg_type_number_t
*var_outputCnt
2865 CHECK( IOUserClient
, connection
, client
);
2867 IOExternalMethodArguments args
;
2869 IOMemoryDescriptor
* inputMD
= 0;
2870 OSObject
* structureVariableOutputData
= 0;
2872 bzero(&args
.__reserved
[0], sizeof(args
.__reserved
));
2873 args
.version
= kIOExternalMethodArgumentsCurrentVersion
;
2875 args
.selector
= selector
;
2877 args
.asyncWakePort
= MACH_PORT_NULL
;
2878 args
.asyncReference
= 0;
2879 args
.asyncReferenceCount
= 0;
2880 args
.structureVariableOutputData
= &structureVariableOutputData
;
2882 args
.scalarInput
= scalar_input
;
2883 args
.scalarInputCount
= scalar_inputCnt
;
2884 args
.structureInput
= inband_input
;
2885 args
.structureInputSize
= inband_inputCnt
;
2888 inputMD
= IOMemoryDescriptor::withAddressRange(ool_input
, ool_input_size
,
2889 kIODirectionOut
, current_task());
2891 args
.structureInputDescriptor
= inputMD
;
2893 args
.scalarOutput
= scalar_output
;
2894 args
.scalarOutputCount
= *scalar_outputCnt
;
2895 args
.structureOutput
= inband_output
;
2896 args
.structureOutputSize
= *inband_outputCnt
;
2897 args
.structureOutputDescriptor
= NULL
;
2898 args
.structureOutputDescriptorSize
= 0;
2900 IOStatisticsClientCall();
2901 ret
= client
->externalMethod( selector
, &args
);
2903 *scalar_outputCnt
= args
.scalarOutputCount
;
2904 *inband_outputCnt
= args
.structureOutputSize
;
2906 if (var_outputCnt
&& var_output
&& (kIOReturnSuccess
== ret
))
2908 OSSerialize
* serialize
;
2912 if ((serialize
= OSDynamicCast(OSSerialize
, structureVariableOutputData
)))
2914 len
= serialize
->getLength();
2915 *var_outputCnt
= len
;
2916 ret
= copyoutkdata(serialize
->text(), len
, var_output
);
2918 else if ((data
= OSDynamicCast(OSData
, structureVariableOutputData
)))
2920 len
= data
->getLength();
2921 *var_outputCnt
= len
;
2922 ret
= copyoutkdata(data
->getBytesNoCopy(), len
, var_output
);
2926 ret
= kIOReturnUnderrun
;
2932 if (structureVariableOutputData
)
2933 structureVariableOutputData
->release();
2938 /* Routine io_user_client_method */
2939 kern_return_t is_io_connect_method
2941 io_connect_t connection
,
2943 io_scalar_inband64_t scalar_input
,
2944 mach_msg_type_number_t scalar_inputCnt
,
2945 io_struct_inband_t inband_input
,
2946 mach_msg_type_number_t inband_inputCnt
,
2947 mach_vm_address_t ool_input
,
2948 mach_vm_size_t ool_input_size
,
2949 io_struct_inband_t inband_output
,
2950 mach_msg_type_number_t
*inband_outputCnt
,
2951 io_scalar_inband64_t scalar_output
,
2952 mach_msg_type_number_t
*scalar_outputCnt
,
2953 mach_vm_address_t ool_output
,
2954 mach_vm_size_t
*ool_output_size
2957 CHECK( IOUserClient
, connection
, client
);
2959 IOExternalMethodArguments args
;
2961 IOMemoryDescriptor
* inputMD
= 0;
2962 IOMemoryDescriptor
* outputMD
= 0;
2964 bzero(&args
.__reserved
[0], sizeof(args
.__reserved
));
2965 args
.version
= kIOExternalMethodArgumentsCurrentVersion
;
2967 args
.selector
= selector
;
2969 args
.asyncWakePort
= MACH_PORT_NULL
;
2970 args
.asyncReference
= 0;
2971 args
.asyncReferenceCount
= 0;
2972 args
.structureVariableOutputData
= 0;
2974 args
.scalarInput
= scalar_input
;
2975 args
.scalarInputCount
= scalar_inputCnt
;
2976 args
.structureInput
= inband_input
;
2977 args
.structureInputSize
= inband_inputCnt
;
2980 inputMD
= IOMemoryDescriptor::withAddressRange(ool_input
, ool_input_size
,
2981 kIODirectionOut
, current_task());
2983 args
.structureInputDescriptor
= inputMD
;
2985 args
.scalarOutput
= scalar_output
;
2986 args
.scalarOutputCount
= *scalar_outputCnt
;
2987 args
.structureOutput
= inband_output
;
2988 args
.structureOutputSize
= *inband_outputCnt
;
2990 if (ool_output
&& ool_output_size
)
2992 outputMD
= IOMemoryDescriptor::withAddressRange(ool_output
, *ool_output_size
,
2993 kIODirectionIn
, current_task());
2996 args
.structureOutputDescriptor
= outputMD
;
2997 args
.structureOutputDescriptorSize
= ool_output_size
? *ool_output_size
: 0;
2999 IOStatisticsClientCall();
3000 ret
= client
->externalMethod( selector
, &args
);
3002 *scalar_outputCnt
= args
.scalarOutputCount
;
3003 *inband_outputCnt
= args
.structureOutputSize
;
3004 *ool_output_size
= args
.structureOutputDescriptorSize
;
3009 outputMD
->release();
3014 /* Routine io_async_user_client_method */
3015 kern_return_t is_io_connect_async_method
3017 io_connect_t connection
,
3018 mach_port_t wake_port
,
3019 io_async_ref64_t reference
,
3020 mach_msg_type_number_t referenceCnt
,
3022 io_scalar_inband64_t scalar_input
,
3023 mach_msg_type_number_t scalar_inputCnt
,
3024 io_struct_inband_t inband_input
,
3025 mach_msg_type_number_t inband_inputCnt
,
3026 mach_vm_address_t ool_input
,
3027 mach_vm_size_t ool_input_size
,
3028 io_struct_inband_t inband_output
,
3029 mach_msg_type_number_t
*inband_outputCnt
,
3030 io_scalar_inband64_t scalar_output
,
3031 mach_msg_type_number_t
*scalar_outputCnt
,
3032 mach_vm_address_t ool_output
,
3033 mach_vm_size_t
* ool_output_size
3036 CHECK( IOUserClient
, connection
, client
);
3038 IOExternalMethodArguments args
;
3040 IOMemoryDescriptor
* inputMD
= 0;
3041 IOMemoryDescriptor
* outputMD
= 0;
3043 bzero(&args
.__reserved
[0], sizeof(args
.__reserved
));
3044 args
.version
= kIOExternalMethodArgumentsCurrentVersion
;
3046 reference
[0] = (io_user_reference_t
) wake_port
;
3047 if (vm_map_is_64bit(get_task_map(current_task())))
3048 reference
[0] |= kIOUCAsync64Flag
;
3050 args
.selector
= selector
;
3052 args
.asyncWakePort
= wake_port
;
3053 args
.asyncReference
= reference
;
3054 args
.asyncReferenceCount
= referenceCnt
;
3056 args
.scalarInput
= scalar_input
;
3057 args
.scalarInputCount
= scalar_inputCnt
;
3058 args
.structureInput
= inband_input
;
3059 args
.structureInputSize
= inband_inputCnt
;
3062 inputMD
= IOMemoryDescriptor::withAddressRange(ool_input
, ool_input_size
,
3063 kIODirectionOut
, current_task());
3065 args
.structureInputDescriptor
= inputMD
;
3067 args
.scalarOutput
= scalar_output
;
3068 args
.scalarOutputCount
= *scalar_outputCnt
;
3069 args
.structureOutput
= inband_output
;
3070 args
.structureOutputSize
= *inband_outputCnt
;
3074 outputMD
= IOMemoryDescriptor::withAddressRange(ool_output
, *ool_output_size
,
3075 kIODirectionIn
, current_task());
3078 args
.structureOutputDescriptor
= outputMD
;
3079 args
.structureOutputDescriptorSize
= *ool_output_size
;
3081 IOStatisticsClientCall();
3082 ret
= client
->externalMethod( selector
, &args
);
3084 *inband_outputCnt
= args
.structureOutputSize
;
3085 *ool_output_size
= args
.structureOutputDescriptorSize
;
3090 outputMD
->release();
3095 /* Routine io_connect_method_scalarI_scalarO */
3096 kern_return_t
is_io_connect_method_scalarI_scalarO(
3097 io_object_t connect
,
3099 io_scalar_inband_t input
,
3100 mach_msg_type_number_t inputCount
,
3101 io_scalar_inband_t output
,
3102 mach_msg_type_number_t
* outputCount
)
3106 io_scalar_inband64_t _input
;
3107 io_scalar_inband64_t _output
;
3109 mach_msg_type_number_t struct_outputCnt
= 0;
3110 mach_vm_size_t ool_output_size
= 0;
3112 for (i
= 0; i
< inputCount
; i
++)
3113 _input
[i
] = SCALAR64(input
[i
]);
3115 err
= is_io_connect_method(connect
, index
,
3119 NULL
, &struct_outputCnt
,
3120 _output
, outputCount
,
3121 0, &ool_output_size
);
3123 for (i
= 0; i
< *outputCount
; i
++)
3124 output
[i
] = SCALAR32(_output
[i
]);
3129 kern_return_t
shim_io_connect_method_scalarI_scalarO(
3130 IOExternalMethod
* method
,
3132 const io_user_scalar_t
* input
,
3133 mach_msg_type_number_t inputCount
,
3134 io_user_scalar_t
* output
,
3135 mach_msg_type_number_t
* outputCount
)
3138 io_scalar_inband_t _output
;
3140 err
= kIOReturnBadArgument
;
3144 if( inputCount
!= method
->count0
)
3146 IOLog("%s: IOUserClient inputCount count mismatch\n", object
->getName());
3149 if( *outputCount
!= method
->count1
)
3151 IOLog("%s: IOUserClient outputCount count mismatch\n", object
->getName());
3155 func
= method
->func
;
3157 switch( inputCount
) {
3160 err
= (object
->*func
)( ARG32(input
[0]), ARG32(input
[1]), ARG32(input
[2]),
3161 ARG32(input
[3]), ARG32(input
[4]), ARG32(input
[5]) );
3164 err
= (object
->*func
)( ARG32(input
[0]), ARG32(input
[1]), ARG32(input
[2]),
3165 ARG32(input
[3]), ARG32(input
[4]),
3169 err
= (object
->*func
)( ARG32(input
[0]), ARG32(input
[1]), ARG32(input
[2]),
3171 &_output
[0], &_output
[1] );
3174 err
= (object
->*func
)( ARG32(input
[0]), ARG32(input
[1]), ARG32(input
[2]),
3175 &_output
[0], &_output
[1], &_output
[2] );
3178 err
= (object
->*func
)( ARG32(input
[0]), ARG32(input
[1]),
3179 &_output
[0], &_output
[1], &_output
[2],
3183 err
= (object
->*func
)( ARG32(input
[0]),
3184 &_output
[0], &_output
[1], &_output
[2],
3185 &_output
[3], &_output
[4] );
3188 err
= (object
->*func
)( &_output
[0], &_output
[1], &_output
[2],
3189 &_output
[3], &_output
[4], &_output
[5] );
3193 IOLog("%s: Bad method table\n", object
->getName());
3199 for (i
= 0; i
< *outputCount
; i
++)
3200 output
[i
] = SCALAR32(_output
[i
]);
3205 /* Routine io_async_method_scalarI_scalarO */
3206 kern_return_t
is_io_async_method_scalarI_scalarO(
3207 io_object_t connect
,
3208 mach_port_t wake_port
,
3209 io_async_ref_t reference
,
3210 mach_msg_type_number_t referenceCnt
,
3212 io_scalar_inband_t input
,
3213 mach_msg_type_number_t inputCount
,
3214 io_scalar_inband_t output
,
3215 mach_msg_type_number_t
* outputCount
)
3219 io_scalar_inband64_t _input
;
3220 io_scalar_inband64_t _output
;
3221 io_async_ref64_t _reference
;
3223 for (i
= 0; i
< referenceCnt
; i
++)
3224 _reference
[i
] = REF64(reference
[i
]);
3226 mach_msg_type_number_t struct_outputCnt
= 0;
3227 mach_vm_size_t ool_output_size
= 0;
3229 for (i
= 0; i
< inputCount
; i
++)
3230 _input
[i
] = SCALAR64(input
[i
]);
3232 err
= is_io_connect_async_method(connect
,
3233 wake_port
, _reference
, referenceCnt
,
3238 NULL
, &struct_outputCnt
,
3239 _output
, outputCount
,
3240 0, &ool_output_size
);
3242 for (i
= 0; i
< *outputCount
; i
++)
3243 output
[i
] = SCALAR32(_output
[i
]);
3247 /* Routine io_async_method_scalarI_structureO */
3248 kern_return_t
is_io_async_method_scalarI_structureO(
3249 io_object_t connect
,
3250 mach_port_t wake_port
,
3251 io_async_ref_t reference
,
3252 mach_msg_type_number_t referenceCnt
,
3254 io_scalar_inband_t input
,
3255 mach_msg_type_number_t inputCount
,
3256 io_struct_inband_t output
,
3257 mach_msg_type_number_t
* outputCount
)
3260 io_scalar_inband64_t _input
;
3261 io_async_ref64_t _reference
;
3263 for (i
= 0; i
< referenceCnt
; i
++)
3264 _reference
[i
] = REF64(reference
[i
]);
3266 mach_msg_type_number_t scalar_outputCnt
= 0;
3267 mach_vm_size_t ool_output_size
= 0;
3269 for (i
= 0; i
< inputCount
; i
++)
3270 _input
[i
] = SCALAR64(input
[i
]);
3272 return (is_io_connect_async_method(connect
,
3273 wake_port
, _reference
, referenceCnt
,
3278 output
, outputCount
,
3279 NULL
, &scalar_outputCnt
,
3280 0, &ool_output_size
));
3283 /* Routine io_async_method_scalarI_structureI */
3284 kern_return_t
is_io_async_method_scalarI_structureI(
3285 io_connect_t connect
,
3286 mach_port_t wake_port
,
3287 io_async_ref_t reference
,
3288 mach_msg_type_number_t referenceCnt
,
3290 io_scalar_inband_t input
,
3291 mach_msg_type_number_t inputCount
,
3292 io_struct_inband_t inputStruct
,
3293 mach_msg_type_number_t inputStructCount
)
3296 io_scalar_inband64_t _input
;
3297 io_async_ref64_t _reference
;
3299 for (i
= 0; i
< referenceCnt
; i
++)
3300 _reference
[i
] = REF64(reference
[i
]);
3302 mach_msg_type_number_t scalar_outputCnt
= 0;
3303 mach_msg_type_number_t inband_outputCnt
= 0;
3304 mach_vm_size_t ool_output_size
= 0;
3306 for (i
= 0; i
< inputCount
; i
++)
3307 _input
[i
] = SCALAR64(input
[i
]);
3309 return (is_io_connect_async_method(connect
,
3310 wake_port
, _reference
, referenceCnt
,
3313 inputStruct
, inputStructCount
,
3315 NULL
, &inband_outputCnt
,
3316 NULL
, &scalar_outputCnt
,
3317 0, &ool_output_size
));
3320 /* Routine io_async_method_structureI_structureO */
3321 kern_return_t
is_io_async_method_structureI_structureO(
3322 io_object_t connect
,
3323 mach_port_t wake_port
,
3324 io_async_ref_t reference
,
3325 mach_msg_type_number_t referenceCnt
,
3327 io_struct_inband_t input
,
3328 mach_msg_type_number_t inputCount
,
3329 io_struct_inband_t output
,
3330 mach_msg_type_number_t
* outputCount
)
3333 mach_msg_type_number_t scalar_outputCnt
= 0;
3334 mach_vm_size_t ool_output_size
= 0;
3335 io_async_ref64_t _reference
;
3337 for (i
= 0; i
< referenceCnt
; i
++)
3338 _reference
[i
] = REF64(reference
[i
]);
3340 return (is_io_connect_async_method(connect
,
3341 wake_port
, _reference
, referenceCnt
,
3346 output
, outputCount
,
3347 NULL
, &scalar_outputCnt
,
3348 0, &ool_output_size
));
3352 kern_return_t
shim_io_async_method_scalarI_scalarO(
3353 IOExternalAsyncMethod
* method
,
3355 mach_port_t asyncWakePort
,
3356 io_user_reference_t
* asyncReference
,
3357 uint32_t asyncReferenceCount
,
3358 const io_user_scalar_t
* input
,
3359 mach_msg_type_number_t inputCount
,
3360 io_user_scalar_t
* output
,
3361 mach_msg_type_number_t
* outputCount
)
3365 io_scalar_inband_t _output
;
3367 io_async_ref_t reference
;
3369 for (i
= 0; i
< asyncReferenceCount
; i
++)
3370 reference
[i
] = REF32(asyncReference
[i
]);
3372 err
= kIOReturnBadArgument
;
3376 if( inputCount
!= method
->count0
)
3378 IOLog("%s: IOUserClient inputCount count mismatch\n", object
->getName());
3381 if( *outputCount
!= method
->count1
)
3383 IOLog("%s: IOUserClient outputCount count mismatch\n", object
->getName());
3387 func
= method
->func
;
3389 switch( inputCount
) {
3392 err
= (object
->*func
)( reference
,
3393 ARG32(input
[0]), ARG32(input
[1]), ARG32(input
[2]),
3394 ARG32(input
[3]), ARG32(input
[4]), ARG32(input
[5]) );
3397 err
= (object
->*func
)( reference
,
3398 ARG32(input
[0]), ARG32(input
[1]), ARG32(input
[2]),
3399 ARG32(input
[3]), ARG32(input
[4]),
3403 err
= (object
->*func
)( reference
,
3404 ARG32(input
[0]), ARG32(input
[1]), ARG32(input
[2]),
3406 &_output
[0], &_output
[1] );
3409 err
= (object
->*func
)( reference
,
3410 ARG32(input
[0]), ARG32(input
[1]), ARG32(input
[2]),
3411 &_output
[0], &_output
[1], &_output
[2] );
3414 err
= (object
->*func
)( reference
,
3415 ARG32(input
[0]), ARG32(input
[1]),
3416 &_output
[0], &_output
[1], &_output
[2],
3420 err
= (object
->*func
)( reference
,
3422 &_output
[0], &_output
[1], &_output
[2],
3423 &_output
[3], &_output
[4] );
3426 err
= (object
->*func
)( reference
,
3427 &_output
[0], &_output
[1], &_output
[2],
3428 &_output
[3], &_output
[4], &_output
[5] );
3432 IOLog("%s: Bad method table\n", object
->getName());
3437 for (i
= 0; i
< *outputCount
; i
++)
3438 output
[i
] = SCALAR32(_output
[i
]);
3444 /* Routine io_connect_method_scalarI_structureO */
3445 kern_return_t
is_io_connect_method_scalarI_structureO(
3446 io_object_t connect
,
3448 io_scalar_inband_t input
,
3449 mach_msg_type_number_t inputCount
,
3450 io_struct_inband_t output
,
3451 mach_msg_type_number_t
* outputCount
)
3454 io_scalar_inband64_t _input
;
3456 mach_msg_type_number_t scalar_outputCnt
= 0;
3457 mach_vm_size_t ool_output_size
= 0;
3459 for (i
= 0; i
< inputCount
; i
++)
3460 _input
[i
] = SCALAR64(input
[i
]);
3462 return (is_io_connect_method(connect
, index
,
3466 output
, outputCount
,
3467 NULL
, &scalar_outputCnt
,
3468 0, &ool_output_size
));
3471 kern_return_t
shim_io_connect_method_scalarI_structureO(
3473 IOExternalMethod
* method
,
3475 const io_user_scalar_t
* input
,
3476 mach_msg_type_number_t inputCount
,
3477 io_struct_inband_t output
,
3478 IOByteCount
* outputCount
)
3483 err
= kIOReturnBadArgument
;
3486 if( inputCount
!= method
->count0
)
3488 IOLog("%s: IOUserClient inputCount count mismatch\n", object
->getName());
3491 if( (kIOUCVariableStructureSize
!= method
->count1
)
3492 && (*outputCount
!= method
->count1
))
3494 IOLog("%s: IOUserClient outputCount count mismatch\n", object
->getName());
3498 func
= method
->func
;
3500 switch( inputCount
) {
3503 err
= (object
->*func
)( ARG32(input
[0]), ARG32(input
[1]), ARG32(input
[2]),
3504 ARG32(input
[3]), ARG32(input
[4]),
3508 err
= (object
->*func
)( ARG32(input
[0]), ARG32(input
[1]), ARG32(input
[2]),
3510 output
, (void *)outputCount
);
3513 err
= (object
->*func
)( ARG32(input
[0]), ARG32(input
[1]), ARG32(input
[2]),
3514 output
, (void *)outputCount
, 0 );
3517 err
= (object
->*func
)( ARG32(input
[0]), ARG32(input
[1]),
3518 output
, (void *)outputCount
, 0, 0 );
3521 err
= (object
->*func
)( ARG32(input
[0]),
3522 output
, (void *)outputCount
, 0, 0, 0 );
3525 err
= (object
->*func
)( output
, (void *)outputCount
, 0, 0, 0, 0 );
3529 IOLog("%s: Bad method table\n", object
->getName());
3538 kern_return_t
shim_io_async_method_scalarI_structureO(
3539 IOExternalAsyncMethod
* method
,
3541 mach_port_t asyncWakePort
,
3542 io_user_reference_t
* asyncReference
,
3543 uint32_t asyncReferenceCount
,
3544 const io_user_scalar_t
* input
,
3545 mach_msg_type_number_t inputCount
,
3546 io_struct_inband_t output
,
3547 mach_msg_type_number_t
* outputCount
)
3552 io_async_ref_t reference
;
3554 for (i
= 0; i
< asyncReferenceCount
; i
++)
3555 reference
[i
] = REF32(asyncReference
[i
]);
3557 err
= kIOReturnBadArgument
;
3559 if( inputCount
!= method
->count0
)
3561 IOLog("%s: IOUserClient inputCount count mismatch\n", object
->getName());
3564 if( (kIOUCVariableStructureSize
!= method
->count1
)
3565 && (*outputCount
!= method
->count1
))
3567 IOLog("%s: IOUserClient outputCount count mismatch\n", object
->getName());
3571 func
= method
->func
;
3573 switch( inputCount
) {
3576 err
= (object
->*func
)( reference
,
3577 ARG32(input
[0]), ARG32(input
[1]), ARG32(input
[2]),
3578 ARG32(input
[3]), ARG32(input
[4]),
3582 err
= (object
->*func
)( reference
,
3583 ARG32(input
[0]), ARG32(input
[1]), ARG32(input
[2]),
3585 output
, (void *)outputCount
);
3588 err
= (object
->*func
)( reference
,
3589 ARG32(input
[0]), ARG32(input
[1]), ARG32(input
[2]),
3590 output
, (void *)outputCount
, 0 );
3593 err
= (object
->*func
)( reference
,
3594 ARG32(input
[0]), ARG32(input
[1]),
3595 output
, (void *)outputCount
, 0, 0 );
3598 err
= (object
->*func
)( reference
,
3600 output
, (void *)outputCount
, 0, 0, 0 );
3603 err
= (object
->*func
)( reference
,
3604 output
, (void *)outputCount
, 0, 0, 0, 0 );
3608 IOLog("%s: Bad method table\n", object
->getName());
3616 /* Routine io_connect_method_scalarI_structureI */
3617 kern_return_t
is_io_connect_method_scalarI_structureI(
3618 io_connect_t connect
,
3620 io_scalar_inband_t input
,
3621 mach_msg_type_number_t inputCount
,
3622 io_struct_inband_t inputStruct
,
3623 mach_msg_type_number_t inputStructCount
)
3626 io_scalar_inband64_t _input
;
3628 mach_msg_type_number_t scalar_outputCnt
= 0;
3629 mach_msg_type_number_t inband_outputCnt
= 0;
3630 mach_vm_size_t ool_output_size
= 0;
3632 for (i
= 0; i
< inputCount
; i
++)
3633 _input
[i
] = SCALAR64(input
[i
]);
3635 return (is_io_connect_method(connect
, index
,
3637 inputStruct
, inputStructCount
,
3639 NULL
, &inband_outputCnt
,
3640 NULL
, &scalar_outputCnt
,
3641 0, &ool_output_size
));
3644 kern_return_t
shim_io_connect_method_scalarI_structureI(
3645 IOExternalMethod
* method
,
3647 const io_user_scalar_t
* input
,
3648 mach_msg_type_number_t inputCount
,
3649 io_struct_inband_t inputStruct
,
3650 mach_msg_type_number_t inputStructCount
)
3653 IOReturn err
= kIOReturnBadArgument
;
3657 if( (kIOUCVariableStructureSize
!= method
->count0
)
3658 && (inputCount
!= method
->count0
))
3660 IOLog("%s: IOUserClient inputCount count mismatch\n", object
->getName());
3663 if( (kIOUCVariableStructureSize
!= method
->count1
)
3664 && (inputStructCount
!= method
->count1
))
3666 IOLog("%s: IOUserClient outputCount count mismatch\n", object
->getName());
3670 func
= method
->func
;
3672 switch( inputCount
) {
3675 err
= (object
->*func
)( ARG32(input
[0]), ARG32(input
[1]), ARG32(input
[2]),
3676 ARG32(input
[3]), ARG32(input
[4]),
3680 err
= (object
->*func
)( ARG32(input
[0]), ARG32(input
[1]), (void *) input
[2],
3682 inputStruct
, (void *)inputStructCount
);
3685 err
= (object
->*func
)( ARG32(input
[0]), ARG32(input
[1]), ARG32(input
[2]),
3686 inputStruct
, (void *)inputStructCount
,
3690 err
= (object
->*func
)( ARG32(input
[0]), ARG32(input
[1]),
3691 inputStruct
, (void *)inputStructCount
,
3695 err
= (object
->*func
)( ARG32(input
[0]),
3696 inputStruct
, (void *)inputStructCount
,
3700 err
= (object
->*func
)( inputStruct
, (void *)inputStructCount
,
3705 IOLog("%s: Bad method table\n", object
->getName());
3713 kern_return_t
shim_io_async_method_scalarI_structureI(
3714 IOExternalAsyncMethod
* method
,
3716 mach_port_t asyncWakePort
,
3717 io_user_reference_t
* asyncReference
,
3718 uint32_t asyncReferenceCount
,
3719 const io_user_scalar_t
* input
,
3720 mach_msg_type_number_t inputCount
,
3721 io_struct_inband_t inputStruct
,
3722 mach_msg_type_number_t inputStructCount
)
3726 IOReturn err
= kIOReturnBadArgument
;
3727 io_async_ref_t reference
;
3729 for (i
= 0; i
< asyncReferenceCount
; i
++)
3730 reference
[i
] = REF32(asyncReference
[i
]);
3734 if( (kIOUCVariableStructureSize
!= method
->count0
)
3735 && (inputCount
!= method
->count0
))
3737 IOLog("%s: IOUserClient inputCount count mismatch\n", object
->getName());
3740 if( (kIOUCVariableStructureSize
!= method
->count1
)
3741 && (inputStructCount
!= method
->count1
))
3743 IOLog("%s: IOUserClient outputCount count mismatch\n", object
->getName());
3747 func
= method
->func
;
3749 switch( inputCount
) {
3752 err
= (object
->*func
)( reference
,
3753 ARG32(input
[0]), ARG32(input
[1]), ARG32(input
[2]),
3754 ARG32(input
[3]), ARG32(input
[4]),
3758 err
= (object
->*func
)( reference
,
3759 ARG32(input
[0]), ARG32(input
[1]), ARG32(input
[2]),
3761 inputStruct
, (void *)inputStructCount
);
3764 err
= (object
->*func
)( reference
,
3765 ARG32(input
[0]), ARG32(input
[1]), ARG32(input
[2]),
3766 inputStruct
, (void *)inputStructCount
,
3770 err
= (object
->*func
)( reference
,
3771 ARG32(input
[0]), ARG32(input
[1]),
3772 inputStruct
, (void *)inputStructCount
,
3776 err
= (object
->*func
)( reference
,
3778 inputStruct
, (void *)inputStructCount
,
3782 err
= (object
->*func
)( reference
,
3783 inputStruct
, (void *)inputStructCount
,
3788 IOLog("%s: Bad method table\n", object
->getName());
3796 /* Routine io_connect_method_structureI_structureO */
3797 kern_return_t
is_io_connect_method_structureI_structureO(
3798 io_object_t connect
,
3800 io_struct_inband_t input
,
3801 mach_msg_type_number_t inputCount
,
3802 io_struct_inband_t output
,
3803 mach_msg_type_number_t
* outputCount
)
3805 mach_msg_type_number_t scalar_outputCnt
= 0;
3806 mach_vm_size_t ool_output_size
= 0;
3808 return (is_io_connect_method(connect
, index
,
3812 output
, outputCount
,
3813 NULL
, &scalar_outputCnt
,
3814 0, &ool_output_size
));
3817 kern_return_t
shim_io_connect_method_structureI_structureO(
3818 IOExternalMethod
* method
,
3820 io_struct_inband_t input
,
3821 mach_msg_type_number_t inputCount
,
3822 io_struct_inband_t output
,
3823 IOByteCount
* outputCount
)
3826 IOReturn err
= kIOReturnBadArgument
;
3830 if( (kIOUCVariableStructureSize
!= method
->count0
)
3831 && (inputCount
!= method
->count0
))
3833 IOLog("%s: IOUserClient inputCount count mismatch\n", object
->getName());
3836 if( (kIOUCVariableStructureSize
!= method
->count1
)
3837 && (*outputCount
!= method
->count1
))
3839 IOLog("%s: IOUserClient outputCount count mismatch\n", object
->getName());
3843 func
= method
->func
;
3845 if( method
->count1
) {
3846 if( method
->count0
) {
3847 err
= (object
->*func
)( input
, output
,
3848 (void *)inputCount
, outputCount
, 0, 0 );
3850 err
= (object
->*func
)( output
, outputCount
, 0, 0, 0, 0 );
3853 err
= (object
->*func
)( input
, (void *)inputCount
, 0, 0, 0, 0 );
3862 kern_return_t
shim_io_async_method_structureI_structureO(
3863 IOExternalAsyncMethod
* method
,
3865 mach_port_t asyncWakePort
,
3866 io_user_reference_t
* asyncReference
,
3867 uint32_t asyncReferenceCount
,
3868 io_struct_inband_t input
,
3869 mach_msg_type_number_t inputCount
,
3870 io_struct_inband_t output
,
3871 mach_msg_type_number_t
* outputCount
)
3876 io_async_ref_t reference
;
3878 for (i
= 0; i
< asyncReferenceCount
; i
++)
3879 reference
[i
] = REF32(asyncReference
[i
]);
3881 err
= kIOReturnBadArgument
;
3884 if( (kIOUCVariableStructureSize
!= method
->count0
)
3885 && (inputCount
!= method
->count0
))
3887 IOLog("%s: IOUserClient inputCount count mismatch\n", object
->getName());
3890 if( (kIOUCVariableStructureSize
!= method
->count1
)
3891 && (*outputCount
!= method
->count1
))
3893 IOLog("%s: IOUserClient outputCount count mismatch\n", object
->getName());
3897 func
= method
->func
;
3899 if( method
->count1
) {
3900 if( method
->count0
) {
3901 err
= (object
->*func
)( reference
,
3903 (void *)inputCount
, outputCount
, 0, 0 );
3905 err
= (object
->*func
)( reference
,
3906 output
, outputCount
, 0, 0, 0, 0 );
3909 err
= (object
->*func
)( reference
,
3910 input
, (void *)inputCount
, 0, 0, 0, 0 );
3918 /* Routine io_catalog_send_data */
3919 kern_return_t
is_io_catalog_send_data(
3920 mach_port_t master_port
,
3922 io_buf_ptr_t inData
,
3923 mach_msg_type_number_t inDataCount
,
3924 kern_return_t
* result
)
3928 kern_return_t kr
= kIOReturnError
;
3930 //printf("io_catalog_send_data called. flag: %d\n", flag);
3932 if( master_port
!= master_device_port
)
3933 return kIOReturnNotPrivileged
;
3935 if( (flag
!= kIOCatalogRemoveKernelLinker
&&
3936 flag
!= kIOCatalogKextdActive
&&
3937 flag
!= kIOCatalogKextdFinishedLaunching
) &&
3938 ( !inData
|| !inDataCount
) )
3940 return kIOReturnBadArgument
;
3944 vm_map_offset_t map_data
;
3946 kr
= vm_map_copyout( kernel_map
, &map_data
, (vm_map_copy_t
)inData
);
3947 data
= CAST_DOWN(vm_offset_t
, map_data
);
3949 if( kr
!= KERN_SUCCESS
)
3952 // must return success after vm_map_copyout() succeeds
3955 obj
= (OSObject
*)OSUnserializeXML((const char *)data
);
3956 vm_deallocate( kernel_map
, data
, inDataCount
);
3958 *result
= kIOReturnNoMemory
;
3959 return( KERN_SUCCESS
);
3965 case kIOCatalogResetDrivers
:
3966 case kIOCatalogResetDriversNoMatch
: {
3969 array
= OSDynamicCast(OSArray
, obj
);
3971 if ( !gIOCatalogue
->resetAndAddDrivers(array
,
3972 flag
== kIOCatalogResetDrivers
) ) {
3974 kr
= kIOReturnError
;
3977 kr
= kIOReturnBadArgument
;
3982 case kIOCatalogAddDrivers
:
3983 case kIOCatalogAddDriversNoMatch
: {
3986 array
= OSDynamicCast(OSArray
, obj
);
3988 if ( !gIOCatalogue
->addDrivers( array
,
3989 flag
== kIOCatalogAddDrivers
) ) {
3990 kr
= kIOReturnError
;
3994 kr
= kIOReturnBadArgument
;
3999 case kIOCatalogRemoveDrivers
:
4000 case kIOCatalogRemoveDriversNoMatch
: {
4001 OSDictionary
* dict
;
4003 dict
= OSDynamicCast(OSDictionary
, obj
);
4005 if ( !gIOCatalogue
->removeDrivers( dict
,
4006 flag
== kIOCatalogRemoveDrivers
) ) {
4007 kr
= kIOReturnError
;
4011 kr
= kIOReturnBadArgument
;
4016 case kIOCatalogStartMatching
: {
4017 OSDictionary
* dict
;
4019 dict
= OSDynamicCast(OSDictionary
, obj
);
4021 if ( !gIOCatalogue
->startMatching( dict
) ) {
4022 kr
= kIOReturnError
;
4026 kr
= kIOReturnBadArgument
;
4031 case kIOCatalogRemoveKernelLinker
:
4032 kr
= KERN_NOT_SUPPORTED
;
4035 case kIOCatalogKextdActive
:
4037 IOServiceTrace(IOSERVICE_KEXTD_ALIVE
, 0, 0, 0, 0);
4038 OSKext::setKextdActive();
4040 /* Dump all nonloaded startup extensions; kextd will now send them
4043 OSKext::flushNonloadedKexts( /* flushPrelinkedKexts */ false);
4045 kr
= kIOReturnSuccess
;
4048 case kIOCatalogKextdFinishedLaunching
: {
4050 static bool clearedBusy
= false;
4053 IOService
* serviceRoot
= IOService::getServiceRoot();
4055 IOServiceTrace(IOSERVICE_KEXTD_READY
, 0, 0, 0, 0);
4056 serviceRoot
->adjustBusy(-1);
4061 kr
= kIOReturnSuccess
;
4066 kr
= kIOReturnBadArgument
;
4070 if (obj
) obj
->release();
4073 return( KERN_SUCCESS
);
4076 /* Routine io_catalog_terminate */
4077 kern_return_t
is_io_catalog_terminate(
4078 mach_port_t master_port
,
4084 if( master_port
!= master_device_port
)
4085 return kIOReturnNotPrivileged
;
4087 kr
= IOUserClient::clientHasPrivilege( (void *) current_task(),
4088 kIOClientPrivilegeAdministrator
);
4089 if( kIOReturnSuccess
!= kr
)
4093 #if !defined(SECURE_KERNEL)
4094 case kIOCatalogServiceTerminate
:
4096 IOService
* service
;
4098 iter
= IORegistryIterator::iterateOver(gIOServicePlane
,
4099 kIORegistryIterateRecursively
);
4101 return kIOReturnNoMemory
;
4105 while( (service
= (IOService
*)iter
->getNextObject()) ) {
4106 if( service
->metaCast(name
)) {
4107 if ( !service
->terminate( kIOServiceRequired
4108 | kIOServiceSynchronous
) ) {
4109 kr
= kIOReturnUnsupported
;
4114 } while( !service
&& !iter
->isValid());
4118 case kIOCatalogModuleUnload
:
4119 case kIOCatalogModuleTerminate
:
4120 kr
= gIOCatalogue
->terminateDriversForModule(name
,
4121 flag
== kIOCatalogModuleUnload
);
4126 kr
= kIOReturnBadArgument
;
4133 /* Routine io_catalog_get_data */
4134 kern_return_t
is_io_catalog_get_data(
4135 mach_port_t master_port
,
4137 io_buf_ptr_t
*outData
,
4138 mach_msg_type_number_t
*outDataCount
)
4140 kern_return_t kr
= kIOReturnSuccess
;
4143 if( master_port
!= master_device_port
)
4144 return kIOReturnNotPrivileged
;
4146 //printf("io_catalog_get_data called. flag: %d\n", flag);
4148 s
= OSSerialize::withCapacity(4096);
4150 return kIOReturnNoMemory
;
4154 kr
= gIOCatalogue
->serializeData(flag
, s
);
4156 if ( kr
== kIOReturnSuccess
) {
4161 size
= s
->getLength();
4162 kr
= vm_allocate(kernel_map
, &data
, size
, VM_FLAGS_ANYWHERE
);
4163 if ( kr
== kIOReturnSuccess
) {
4164 bcopy(s
->text(), (void *)data
, size
);
4165 kr
= vm_map_copyin(kernel_map
, (vm_map_address_t
)data
,
4166 (vm_map_size_t
)size
, true, ©
);
4167 *outData
= (char *)copy
;
4168 *outDataCount
= size
;
4177 /* Routine io_catalog_get_gen_count */
4178 kern_return_t
is_io_catalog_get_gen_count(
4179 mach_port_t master_port
,
4182 if( master_port
!= master_device_port
)
4183 return kIOReturnNotPrivileged
;
4185 //printf("io_catalog_get_gen_count called.\n");
4188 return kIOReturnBadArgument
;
4190 *genCount
= gIOCatalogue
->getGenerationCount();
4192 return kIOReturnSuccess
;
4195 /* Routine io_catalog_module_loaded.
4196 * Is invoked from IOKitLib's IOCatalogueModuleLoaded(). Doesn't seem to be used.
4198 kern_return_t
is_io_catalog_module_loaded(
4199 mach_port_t master_port
,
4202 if( master_port
!= master_device_port
)
4203 return kIOReturnNotPrivileged
;
4205 //printf("io_catalog_module_loaded called. name %s\n", name);
4208 return kIOReturnBadArgument
;
4210 gIOCatalogue
->moduleHasLoaded(name
);
4212 return kIOReturnSuccess
;
4215 kern_return_t
is_io_catalog_reset(
4216 mach_port_t master_port
,
4219 if( master_port
!= master_device_port
)
4220 return kIOReturnNotPrivileged
;
4223 case kIOCatalogResetDefault
:
4224 gIOCatalogue
->reset();
4228 return kIOReturnBadArgument
;
4231 return kIOReturnSuccess
;
4234 kern_return_t
iokit_user_client_trap(struct iokit_user_client_trap_args
*args
)
4236 kern_return_t result
= kIOReturnBadArgument
;
4237 IOUserClient
*userClient
;
4239 if ((userClient
= OSDynamicCast(IOUserClient
,
4240 iokit_lookup_connect_ref_current_task((OSObject
*)(args
->userClientRef
))))) {
4241 IOExternalTrap
*trap
;
4242 IOService
*target
= NULL
;
4244 trap
= userClient
->getTargetAndTrapForIndex(&target
, args
->index
);
4246 if (trap
&& target
) {
4252 result
= (target
->*func
)(args
->p1
, args
->p2
, args
->p3
, args
->p4
, args
->p5
, args
->p6
);
4256 userClient
->release();
4264 IOReturn
IOUserClient::externalMethod( uint32_t selector
, IOExternalMethodArguments
* args
,
4265 IOExternalMethodDispatch
* dispatch
, OSObject
* target
, void * reference
)
4269 IOByteCount structureOutputSize
;
4274 count
= dispatch
->checkScalarInputCount
;
4275 if ((kIOUCVariableStructureSize
!= count
) && (count
!= args
->scalarInputCount
))
4277 return (kIOReturnBadArgument
);
4280 count
= dispatch
->checkStructureInputSize
;
4281 if ((kIOUCVariableStructureSize
!= count
)
4282 && (count
!= ((args
->structureInputDescriptor
)
4283 ? args
->structureInputDescriptor
->getLength() : args
->structureInputSize
)))
4285 return (kIOReturnBadArgument
);
4288 count
= dispatch
->checkScalarOutputCount
;
4289 if ((kIOUCVariableStructureSize
!= count
) && (count
!= args
->scalarOutputCount
))
4291 return (kIOReturnBadArgument
);
4294 count
= dispatch
->checkStructureOutputSize
;
4295 if ((kIOUCVariableStructureSize
!= count
)
4296 && (count
!= ((args
->structureOutputDescriptor
)
4297 ? args
->structureOutputDescriptor
->getLength() : args
->structureOutputSize
)))
4299 return (kIOReturnBadArgument
);
4302 if (dispatch
->function
)
4303 err
= (*dispatch
->function
)(target
, reference
, args
);
4305 err
= kIOReturnNoCompletion
; /* implementator can dispatch */
4311 // pre-Leopard API's don't do ool structs
4312 if (args
->structureInputDescriptor
|| args
->structureOutputDescriptor
)
4314 err
= kIOReturnIPCError
;
4318 structureOutputSize
= args
->structureOutputSize
;
4320 if (args
->asyncWakePort
)
4322 IOExternalAsyncMethod
* method
;
4324 if( !(method
= getAsyncTargetAndMethodForIndex(&object
, selector
)) )
4325 return (kIOReturnUnsupported
);
4327 if (kIOUCForegroundOnly
& method
->flags
)
4329 /* is graphics access denied for current task? */
4330 if (proc_get_task_selfgpuacc_deny() != 0)
4331 return (kIOReturnNotPermitted
);
4334 switch (method
->flags
& kIOUCTypeMask
)
4336 case kIOUCScalarIStructI
:
4337 err
= shim_io_async_method_scalarI_structureI( method
, object
,
4338 args
->asyncWakePort
, args
->asyncReference
, args
->asyncReferenceCount
,
4339 args
->scalarInput
, args
->scalarInputCount
,
4340 (char *)args
->structureInput
, args
->structureInputSize
);
4343 case kIOUCScalarIScalarO
:
4344 err
= shim_io_async_method_scalarI_scalarO( method
, object
,
4345 args
->asyncWakePort
, args
->asyncReference
, args
->asyncReferenceCount
,
4346 args
->scalarInput
, args
->scalarInputCount
,
4347 args
->scalarOutput
, &args
->scalarOutputCount
);
4350 case kIOUCScalarIStructO
:
4351 err
= shim_io_async_method_scalarI_structureO( method
, object
,
4352 args
->asyncWakePort
, args
->asyncReference
, args
->asyncReferenceCount
,
4353 args
->scalarInput
, args
->scalarInputCount
,
4354 (char *) args
->structureOutput
, &args
->structureOutputSize
);
4358 case kIOUCStructIStructO
:
4359 err
= shim_io_async_method_structureI_structureO( method
, object
,
4360 args
->asyncWakePort
, args
->asyncReference
, args
->asyncReferenceCount
,
4361 (char *)args
->structureInput
, args
->structureInputSize
,
4362 (char *) args
->structureOutput
, &args
->structureOutputSize
);
4366 err
= kIOReturnBadArgument
;
4372 IOExternalMethod
* method
;
4374 if( !(method
= getTargetAndMethodForIndex(&object
, selector
)) )
4375 return (kIOReturnUnsupported
);
4377 if (kIOUCForegroundOnly
& method
->flags
)
4379 /* is graphics access denied for current task? */
4380 if (proc_get_task_selfgpuacc_deny() != 0)
4381 return (kIOReturnNotPermitted
);
4385 switch (method
->flags
& kIOUCTypeMask
)
4387 case kIOUCScalarIStructI
:
4388 err
= shim_io_connect_method_scalarI_structureI( method
, object
,
4389 args
->scalarInput
, args
->scalarInputCount
,
4390 (char *) args
->structureInput
, args
->structureInputSize
);
4393 case kIOUCScalarIScalarO
:
4394 err
= shim_io_connect_method_scalarI_scalarO( method
, object
,
4395 args
->scalarInput
, args
->scalarInputCount
,
4396 args
->scalarOutput
, &args
->scalarOutputCount
);
4399 case kIOUCScalarIStructO
:
4400 err
= shim_io_connect_method_scalarI_structureO( method
, object
,
4401 args
->scalarInput
, args
->scalarInputCount
,
4402 (char *) args
->structureOutput
, &structureOutputSize
);
4406 case kIOUCStructIStructO
:
4407 err
= shim_io_connect_method_structureI_structureO( method
, object
,
4408 (char *) args
->structureInput
, args
->structureInputSize
,
4409 (char *) args
->structureOutput
, &structureOutputSize
);
4413 err
= kIOReturnBadArgument
;
4418 args
->structureOutputSize
= structureOutputSize
;
4425 OSMetaClassDefineReservedUnused(IOUserClient
, 0);
4426 OSMetaClassDefineReservedUnused(IOUserClient
, 1);
4428 OSMetaClassDefineReservedUsed(IOUserClient
, 0);
4429 OSMetaClassDefineReservedUsed(IOUserClient
, 1);
4431 OSMetaClassDefineReservedUnused(IOUserClient
, 2);
4432 OSMetaClassDefineReservedUnused(IOUserClient
, 3);
4433 OSMetaClassDefineReservedUnused(IOUserClient
, 4);
4434 OSMetaClassDefineReservedUnused(IOUserClient
, 5);
4435 OSMetaClassDefineReservedUnused(IOUserClient
, 6);
4436 OSMetaClassDefineReservedUnused(IOUserClient
, 7);
4437 OSMetaClassDefineReservedUnused(IOUserClient
, 8);
4438 OSMetaClassDefineReservedUnused(IOUserClient
, 9);
4439 OSMetaClassDefineReservedUnused(IOUserClient
, 10);
4440 OSMetaClassDefineReservedUnused(IOUserClient
, 11);
4441 OSMetaClassDefineReservedUnused(IOUserClient
, 12);
4442 OSMetaClassDefineReservedUnused(IOUserClient
, 13);
4443 OSMetaClassDefineReservedUnused(IOUserClient
, 14);
4444 OSMetaClassDefineReservedUnused(IOUserClient
, 15);